home *** CD-ROM | disk | FTP | other *** search
/ Aminet 8 / Aminet 8 (1995)(GTI - Schatztruhe)[!][Oct 1995].iso / Aminet / dev / gcc / gcc270_src.lha / gcc-2.7.0-amiga / config / pa / pa.c < prev    next >
C/C++ Source or Header  |  1995-06-15  |  129KB  |  4,561 lines

  1. /* Subroutines for insn-output.c for HPPA.
  2.    Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
  3.    Contributed by Tim Moore (moore@cs.utah.edu), based on sparc.c
  4.  
  5. This file is part of GNU CC.
  6.  
  7. GNU CC is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2, or (at your option)
  10. any later version.
  11.  
  12. GNU CC is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with GNU CC; see the file COPYING.  If not, write to
  19. the Free Software Foundation, 59 Temple Place - Suite 330,
  20. Boston, MA 02111-1307, USA.  */
  21.  
  22. #include <stdio.h>
  23. #include "config.h"
  24. #include "rtl.h"
  25. #include "regs.h"
  26. #include "hard-reg-set.h"
  27. #include "real.h"
  28. #include "insn-config.h"
  29. #include "conditions.h"
  30. #include "insn-flags.h"
  31. #include "output.h"
  32. #include "insn-attr.h"
  33. #include "flags.h"
  34. #include "tree.h"
  35. #include "c-tree.h"
  36. #include "expr.h"
  37. #include "obstack.h"
  38.  
  39. /* Save the operands last given to a compare for use when we
  40.    generate a scc or bcc insn.  */
  41.  
  42. rtx hppa_compare_op0, hppa_compare_op1;
  43. enum cmp_type hppa_branch_type;
  44.  
  45. /* Which cpu we are scheduling for.  */
  46. enum processor_type pa_cpu;
  47.  
  48. /* String to hold which cpu we are scheduling for.  */
  49. char *pa_cpu_string;
  50.  
  51. rtx hppa_save_pic_table_rtx;
  52.  
  53. /* Set by the FUNCTION_PROFILER macro. */
  54. int hp_profile_labelno;
  55.  
  56. /* Counts for the number of callee-saved general and floating point
  57.    registers which were saved by the current function's prologue.  */
  58. static int gr_saved, fr_saved;
  59.  
  60. static rtx find_addr_reg ();
  61.  
  62. /* Keep track of the number of bytes we have output in the CODE subspaces
  63.    during this compilation so we'll know when to emit inline long-calls.  */
  64.  
  65. unsigned int total_code_bytes;
  66.  
  67. /* Variables to handle plabels that we discover are necessary at assembly
  68.    output time.  They are output after the current function.  */
  69.  
  70. struct defer_plab
  71. {
  72.   rtx internal_label;
  73.   rtx symbol;
  74. } *deferred_plabels = 0;
  75. int n_deferred_plabels = 0;
  76.  
  77. void
  78. override_options ()
  79. {
  80.   /* Default to 700 scheduling which is reasonable for older 800 processors
  81.      correct for the 700s, and not too bad for the 7100s and 7100LCs.  */
  82.   if (pa_cpu_string == NULL
  83.       || ! strcmp (pa_cpu_string, "700"))
  84.     {
  85.       pa_cpu_string = "700";
  86.       pa_cpu = PROCESSOR_700;
  87.     }
  88.   else if (! strcmp (pa_cpu_string, "7100"))
  89.     {
  90.       pa_cpu_string = "7100";
  91.       pa_cpu = PROCESSOR_7100;
  92.     }
  93.   else if (! strcmp (pa_cpu_string, "7100LC"))
  94.     {
  95.       pa_cpu_string = "7100LC";
  96.       pa_cpu = PROCESSOR_7100LC;
  97.     }
  98.   else
  99.     {
  100.       warning ("Unknown -mschedule= option (%s).\nValid options are 700, 7100 and 7100LC\n", pa_cpu_string);
  101.     }
  102. }
  103.  
  104.  
  105. /* Return non-zero only if OP is a register of mode MODE,
  106.    or CONST0_RTX.  */
  107. int
  108. reg_or_0_operand (op, mode)
  109.      rtx op;
  110.      enum machine_mode mode;
  111. {
  112.   return (op == CONST0_RTX (mode) || register_operand (op, mode));
  113. }
  114.  
  115. /* Return non-zero if OP is suitable for use in a call to a named
  116.    function.
  117.  
  118.    (???) For 2.5 try to eliminate either call_operand_address or
  119.    function_label_operand, they perform very similar functions.  */
  120. int
  121. call_operand_address (op, mode)
  122.      rtx op;
  123.      enum machine_mode mode;
  124. {
  125.   return (CONSTANT_P (op) && ! TARGET_PORTABLE_RUNTIME);
  126. }
  127.  
  128. /* Return 1 if X contains a symbolic expression.  We know these
  129.    expressions will have one of a few well defined forms, so
  130.    we need only check those forms.  */
  131. int
  132. symbolic_expression_p (x)
  133.      register rtx x;
  134. {
  135.  
  136.   /* Strip off any HIGH. */
  137.   if (GET_CODE (x) == HIGH)
  138.     x = XEXP (x, 0);
  139.  
  140.   return (symbolic_operand (x, VOIDmode));
  141. }
  142.  
  143. int
  144. symbolic_operand (op, mode)
  145.      register rtx op;
  146.      enum machine_mode mode;
  147. {
  148.   switch (GET_CODE (op))
  149.     {
  150.     case SYMBOL_REF:
  151.     case LABEL_REF:
  152.       return 1;
  153.     case CONST:
  154.       op = XEXP (op, 0);
  155.       return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
  156.            || GET_CODE (XEXP (op, 0)) == LABEL_REF)
  157.           && GET_CODE (XEXP (op, 1)) == CONST_INT);
  158.     default:
  159.       return 0;
  160.     }
  161. }
  162.  
  163. /* Return truth value of statement that OP is a symbolic memory
  164.    operand of mode MODE.  */
  165.  
  166. int
  167. symbolic_memory_operand (op, mode)
  168.      rtx op;
  169.      enum machine_mode mode;
  170. {
  171.   if (GET_CODE (op) == SUBREG)
  172.     op = SUBREG_REG (op);
  173.   if (GET_CODE (op) != MEM)
  174.     return 0;
  175.   op = XEXP (op, 0);
  176.   return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST
  177.       || GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF);
  178. }
  179.  
  180. /* Return 1 if the operand is either a register or a memory operand that is
  181.    not symbolic.  */
  182.  
  183. int
  184. reg_or_nonsymb_mem_operand (op, mode)
  185.     register rtx op;
  186.     enum machine_mode mode;
  187. {
  188.   if (register_operand (op, mode))
  189.     return 1;
  190.  
  191.   if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode))
  192.     return 1;
  193.  
  194.   return 0;
  195. }
  196.  
  197. /* Return 1 if the operand is either a register, zero, or a memory operand
  198.    that is not symbolic.  */
  199.  
  200. int
  201. reg_or_0_or_nonsymb_mem_operand (op, mode)
  202.     register rtx op;
  203.     enum machine_mode mode;
  204. {
  205.   if (register_operand (op, mode))
  206.     return 1;
  207.  
  208.   if (op == CONST0_RTX (mode))
  209.     return 1;
  210.  
  211.   if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode))
  212.     return 1;
  213.  
  214.   return 0;
  215. }
  216.  
  217. /* Accept any constant that can be moved in one instructions into a
  218.    general register.  */
  219. int
  220. cint_ok_for_move (intval)
  221.      HOST_WIDE_INT intval;
  222. {
  223.   /* OK if ldo, ldil, or zdepi, can be used.  */
  224.   return (VAL_14_BITS_P (intval) || (intval & 0x7ff) == 0
  225.       || zdepi_cint_p (intval));
  226. }
  227.  
  228. /* Accept anything that can be moved in one instruction into a general
  229.    register.  */
  230. int
  231. move_operand (op, mode)
  232.      rtx op;
  233.      enum machine_mode mode;
  234. {
  235.   if (register_operand (op, mode))
  236.     return 1;
  237.  
  238.   if (GET_CODE (op) == CONST_INT)
  239.     return cint_ok_for_move (INTVAL (op));
  240.  
  241.   if (GET_MODE (op) != mode)
  242.     return 0;
  243.   if (GET_CODE (op) == SUBREG)
  244.     op = SUBREG_REG (op);
  245.   if (GET_CODE (op) != MEM)
  246.     return 0;
  247.  
  248.   op = XEXP (op, 0);
  249.   if (GET_CODE (op) == LO_SUM)
  250.     return (register_operand (XEXP (op, 0), Pmode)
  251.         && CONSTANT_P (XEXP (op, 1)));
  252.   return memory_address_p (mode, op);
  253. }
  254.  
  255. /* Accept REG and any CONST_INT that can be moved in one instruction into a
  256.    general register.  */
  257. int
  258. reg_or_cint_move_operand (op, mode)
  259.      rtx op;
  260.      enum machine_mode mode;
  261. {
  262.   if (register_operand (op, mode))
  263.     return 1;
  264.  
  265.   if (GET_CODE (op) == CONST_INT)
  266.     return cint_ok_for_move (INTVAL (op));
  267.  
  268.   return 0;
  269. }
  270.  
  271. int
  272. pic_label_operand (op, mode)
  273.      rtx op;
  274.      enum machine_mode mode;
  275. {
  276.   if (!flag_pic)
  277.     return 0;
  278.  
  279.   switch (GET_CODE (op))
  280.     {
  281.     case LABEL_REF:
  282.       return 1;
  283.     case CONST:
  284.       op = XEXP (op, 0);
  285.       return (GET_CODE (XEXP (op, 0)) == LABEL_REF
  286.           && GET_CODE (XEXP (op, 1)) == CONST_INT);
  287.     default:
  288.       return 0;
  289.     }
  290. }
  291.  
  292. int
  293. fp_reg_operand (op, mode)
  294.      rtx op;
  295.      enum machine_mode mode;
  296. {
  297.   return reg_renumber && FP_REG_P (op);
  298. }
  299.  
  300.  
  301.  
  302. /* Return truth value of whether OP can be used as an operand in a
  303.    three operand arithmetic insn that accepts registers of mode MODE
  304.    or 14-bit signed integers.  */
  305. int
  306. arith_operand (op, mode)
  307.      rtx op;
  308.      enum machine_mode mode;
  309. {
  310.   return (register_operand (op, mode)
  311.       || (GET_CODE (op) == CONST_INT && INT_14_BITS (op)));
  312. }
  313.  
  314. /* Return truth value of whether OP can be used as an operand in a
  315.    three operand arithmetic insn that accepts registers of mode MODE
  316.    or 11-bit signed integers.  */
  317. int
  318. arith11_operand (op, mode)
  319.      rtx op;
  320.      enum machine_mode mode;
  321. {
  322.   return (register_operand (op, mode)
  323.       || (GET_CODE (op) == CONST_INT && INT_11_BITS (op)));
  324. }
  325.  
  326. /* A constant integer suitable for use in a PRE_MODIFY memory
  327.    reference.  */
  328. int
  329. pre_cint_operand (op, mode)
  330.      rtx op;
  331.      enum machine_mode mode;
  332. {
  333.   return (GET_CODE (op) == CONST_INT
  334.       && INTVAL (op) >= -0x2000 && INTVAL (op) < 0x10);
  335. }
  336.  
  337. /* A constant integer suitable for use in a POST_MODIFY memory
  338.    reference.  */
  339. int
  340. post_cint_operand (op, mode)
  341.      rtx op;
  342.      enum machine_mode mode;
  343. {
  344.   return (GET_CODE (op) == CONST_INT
  345.       && INTVAL (op) < 0x2000 && INTVAL (op) >= -0x10);
  346. }
  347.  
  348. int
  349. arith_double_operand (op, mode)
  350.      rtx op;
  351.      enum machine_mode mode;
  352. {
  353.   return (register_operand (op, mode)
  354.       || (GET_CODE (op) == CONST_DOUBLE
  355.           && GET_MODE (op) == mode
  356.           && VAL_14_BITS_P (CONST_DOUBLE_LOW (op))
  357.           && (CONST_DOUBLE_HIGH (op) >= 0
  358.           == ((CONST_DOUBLE_LOW (op) & 0x1000) == 0))));
  359. }
  360.  
  361. /* Return truth value of whether OP is a integer which fits the
  362.    range constraining immediate operands in three-address insns.  */
  363.  
  364. int
  365. int5_operand (op, mode)
  366.      rtx op;
  367.      enum machine_mode mode;
  368. {
  369.   return (GET_CODE (op) == CONST_INT && INT_5_BITS (op));
  370. }
  371.  
  372. int
  373. uint5_operand (op, mode)
  374.      rtx op;
  375.      enum machine_mode mode;
  376. {
  377.   return (GET_CODE (op) == CONST_INT && INT_U5_BITS (op));
  378. }
  379.  
  380. int
  381. int11_operand (op, mode)
  382.      rtx op;
  383.      enum machine_mode mode;
  384. {
  385.   return (GET_CODE (op) == CONST_INT && INT_11_BITS (op));
  386. }
  387.  
  388. int
  389. uint32_operand (op, mode)
  390.      rtx op;
  391.      enum machine_mode mode;
  392. {
  393. #if HOST_BITS_PER_WIDE_INT > 32
  394.   /* All allowed constants will fit a CONST_INT.  */
  395.   return (GET_CODE (op) == CONST_INT
  396.       && (INTVAL (op) >= 0 && INTVAL (op) < 0x100000000L));
  397. #else
  398.   return (GET_CODE (op) == CONST_INT
  399.       || (GET_CODE (op) == CONST_DOUBLE
  400.           && CONST_DOUBLE_HIGH (op) == 0));
  401. #endif
  402. }
  403.  
  404. int
  405. arith5_operand (op, mode)
  406.      rtx op;
  407.      enum machine_mode mode;
  408. {
  409.   return register_operand (op, mode) || int5_operand (op, mode);
  410. }
  411.  
  412. /* True iff zdepi can be used to generate this CONST_INT.  */
  413. int
  414. zdepi_cint_p (x)
  415.      unsigned HOST_WIDE_INT x;
  416. {
  417.   unsigned HOST_WIDE_INT lsb_mask, t;
  418.  
  419.   /* This might not be obvious, but it's at least fast.
  420.      This function is critical; we don't have the time loops would take.  */
  421.   lsb_mask = x & -x;
  422.   t = ((x >> 4) + lsb_mask) & ~(lsb_mask - 1);
  423.   /* Return true iff t is a power of two.  */
  424.   return ((t & (t - 1)) == 0);
  425. }
  426.  
  427. /* True iff depi or extru can be used to compute (reg & mask).
  428.    Accept bit pattern like these:
  429.    0....01....1
  430.    1....10....0
  431.    1..10..01..1  */
  432. int
  433. and_mask_p (mask)
  434.      unsigned HOST_WIDE_INT mask;
  435. {
  436.   mask = ~mask;
  437.   mask += mask & -mask;
  438.   return (mask & (mask - 1)) == 0;
  439. }
  440.  
  441. /* True iff depi or extru can be used to compute (reg & OP).  */
  442. int
  443. and_operand (op, mode)
  444.      rtx op;
  445.      enum machine_mode mode;
  446. {
  447.   return (register_operand (op, mode)
  448.       || (GET_CODE (op) == CONST_INT && and_mask_p (INTVAL (op))));
  449. }
  450.  
  451. /* True iff depi can be used to compute (reg | MASK).  */
  452. int
  453. ior_mask_p (mask)
  454.      unsigned HOST_WIDE_INT mask;
  455. {
  456.   mask += mask & -mask;
  457.   return (mask & (mask - 1)) == 0;
  458. }
  459.  
  460. /* True iff depi can be used to compute (reg | OP).  */
  461. int
  462. ior_operand (op, mode)
  463.      rtx op;
  464.      enum machine_mode mode;
  465. {
  466.   return (GET_CODE (op) == CONST_INT && ior_mask_p (INTVAL (op)));
  467. }
  468.  
  469. int
  470. lhs_lshift_operand (op, mode)
  471.      rtx op;
  472.      enum machine_mode mode;
  473. {
  474.   return register_operand (op, mode) || lhs_lshift_cint_operand (op, mode);
  475. }
  476.  
  477. /* True iff OP is a CONST_INT of the forms 0...0xxxx or 0...01...1xxxx.
  478.    Such values can be the left hand side x in (x << r), using the zvdepi
  479.    instruction.  */
  480. int
  481. lhs_lshift_cint_operand (op, mode)
  482.      rtx op;
  483.      enum machine_mode mode;
  484. {
  485.   unsigned HOST_WIDE_INT x;
  486.   if (GET_CODE (op) != CONST_INT)
  487.     return 0;
  488.   x = INTVAL (op) >> 4;
  489.   return (x & (x + 1)) == 0;
  490. }
  491.  
  492. int
  493. arith32_operand (op, mode)
  494.      rtx op;
  495.      enum machine_mode mode;
  496. {
  497.   return register_operand (op, mode) || GET_CODE (op) == CONST_INT;
  498. }
  499.  
  500. int
  501. pc_or_label_operand (op, mode)
  502.      rtx op;
  503.      enum machine_mode mode;
  504. {
  505.   return (GET_CODE (op) == PC || GET_CODE (op) == LABEL_REF);
  506. }
  507.  
  508. /* Legitimize PIC addresses.  If the address is already
  509.    position-independent, we return ORIG.  Newly generated
  510.    position-independent addresses go to REG.  If we need more
  511.    than one register, we lose.  */
  512.  
  513. rtx
  514. legitimize_pic_address (orig, mode, reg)
  515.      rtx orig, reg;
  516.      enum machine_mode mode;
  517. {
  518.   rtx pic_ref = orig;
  519.  
  520.   /* Lables need special handling.  */
  521.   if (pic_label_operand (orig))
  522.     {
  523.       emit_insn (gen_pic_load_label (reg, orig));
  524.       current_function_uses_pic_offset_table = 1;
  525.       return reg;
  526.     }
  527.   if (GET_CODE (orig) == SYMBOL_REF)
  528.     {
  529.       if (reg == 0)
  530.     abort ();
  531.  
  532.       if (flag_pic == 2)
  533.     {
  534.       emit_insn (gen_pic2_highpart (reg, pic_offset_table_rtx, orig));
  535.       pic_ref = gen_rtx (MEM, Pmode,
  536.                  gen_rtx (LO_SUM, Pmode, reg,
  537.                       gen_rtx (UNSPEC, SImode, gen_rtvec (1, orig), 0)));
  538.     }
  539.       else
  540.     pic_ref = gen_rtx (MEM, Pmode,
  541.                gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig));
  542.       current_function_uses_pic_offset_table = 1;
  543.       RTX_UNCHANGING_P (pic_ref) = 1;
  544.       emit_move_insn (reg, pic_ref);
  545.       return reg;
  546.     }
  547.   else if (GET_CODE (orig) == CONST)
  548.     {
  549.       rtx base;
  550.  
  551.       if (GET_CODE (XEXP (orig, 0)) == PLUS
  552.       && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
  553.     return orig;
  554.  
  555.       if (reg == 0)
  556.     abort ();
  557.  
  558.       if (GET_CODE (XEXP (orig, 0)) == PLUS)
  559.     {
  560.       base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
  561.       orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
  562.                      base == reg ? 0 : reg);
  563.     }
  564.       else abort ();
  565.       if (GET_CODE (orig) == CONST_INT)
  566.     {
  567.       if (INT_14_BITS (orig))
  568.         return plus_constant_for_output (base, INTVAL (orig));
  569.       orig = force_reg (Pmode, orig);
  570.     }
  571.       pic_ref = gen_rtx (PLUS, Pmode, base, orig);
  572.       /* Likewise, should we set special REG_NOTEs here?  */
  573.     }
  574.   return pic_ref;
  575. }
  576.  
  577. /* Try machine-dependent ways of modifying an illegitimate address
  578.    to be legitimate.  If we find one, return the new, valid address.
  579.    This macro is used in only one place: `memory_address' in explow.c.
  580.  
  581.    OLDX is the address as it was before break_out_memory_refs was called.
  582.    In some cases it is useful to look at this to decide what needs to be done.
  583.  
  584.    MODE and WIN are passed so that this macro can use
  585.    GO_IF_LEGITIMATE_ADDRESS.
  586.  
  587.    It is always safe for this macro to do nothing.  It exists to recognize
  588.    opportunities to optimize the output.
  589.  
  590.    For the PA, transform:
  591.  
  592.     memory(X + <large int>)
  593.  
  594.    into:
  595.  
  596.     if (<large int> & mask) >= 16
  597.       Y = (<large int> & ~mask) + mask + 1    Round up.
  598.     else
  599.       Y = (<large int> & ~mask)        Round down.
  600.     Z = X + Y
  601.     memory (Z + (<large int> - Y));
  602.  
  603.    This is for CSE to find several similar references, and only use one Z.
  604.  
  605.    X can either be a SYMBOL_REF or REG, but because combine can not
  606.    perform a 4->2 combination we do nothing for SYMBOL_REF + D where
  607.    D will not fit in 14 bits.
  608.  
  609.    MODE_FLOAT references allow displacements which fit in 5 bits, so use
  610.    0x1f as the mask.
  611.  
  612.    MODE_INT references allow displacements which fit in 14 bits, so use
  613.    0x3fff as the mask.
  614.  
  615.    This relies on the fact that most mode MODE_FLOAT references will use FP
  616.    registers and most mode MODE_INT references will use integer registers.
  617.    (In the rare case of an FP register used in an integer MODE, we depend
  618.    on secondary reloads to clean things up.)
  619.  
  620.  
  621.    It is also beneficial to handle (plus (mult (X) (Y)) (Z)) in a special
  622.    manner if Y is 2, 4, or 8.  (allows more shadd insns and shifted indexed
  623.    addressing modes to be used).
  624.  
  625.    Put X and Z into registers.  Then put the entire expression into
  626.    a register.  */
  627.  
  628. rtx
  629. hppa_legitimize_address (x, oldx, mode)
  630.      rtx x, oldx;
  631.      enum machine_mode mode;
  632. {
  633.   rtx orig = x;
  634.  
  635.   if (flag_pic)
  636.     return legitimize_pic_address (x, mode, gen_reg_rtx (Pmode));
  637.  
  638.   /* Strip off CONST. */
  639.   if (GET_CODE (x) == CONST)
  640.     x = XEXP (x, 0);
  641.  
  642.   /* Note we must reject symbols which represent function addresses
  643.      since the assembler/linker can't handle arithmetic on plabels.  */
  644.   if (GET_CODE (x) == PLUS
  645.       && GET_CODE (XEXP (x, 1)) == CONST_INT
  646.       && ((GET_CODE (XEXP (x, 0)) == SYMBOL_REF
  647.        && !FUNCTION_NAME_P (XSTR (XEXP (x, 0), 0)))
  648.       || GET_CODE (XEXP (x, 0)) == REG))
  649.     {
  650.       rtx int_part, ptr_reg;
  651.       int newoffset;
  652.       int offset = INTVAL (XEXP (x, 1));
  653.       int mask = GET_MODE_CLASS (mode) == MODE_FLOAT ? 0x1f : 0x3fff;
  654.  
  655.       /* Choose which way to round the offset.  Round up if we
  656.      are >= halfway to the next boundary.  */
  657.       if ((offset & mask) >= ((mask + 1) / 2))
  658.     newoffset = (offset & ~ mask) + mask + 1;
  659.       else
  660.     newoffset = (offset & ~ mask);
  661.  
  662.       /* If the newoffset will not fit in 14 bits (ldo), then
  663.      handling this would take 4 or 5 instructions (2 to load
  664.      the SYMBOL_REF + 1 or 2 to load the newoffset + 1 to
  665.      add the new offset and the SYMBOL_REF.)  Combine can
  666.      not handle 4->2 or 5->2 combinations, so do not create
  667.      them.  */
  668.       if (! VAL_14_BITS_P (newoffset)
  669.       && GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
  670.     {
  671.       rtx const_part = gen_rtx (CONST, VOIDmode,
  672.                     gen_rtx (PLUS, Pmode,
  673.                          XEXP (x, 0),
  674.                          GEN_INT (newoffset)));
  675.       rtx tmp_reg
  676.         = force_reg (Pmode,
  677.              gen_rtx (HIGH, Pmode, const_part));
  678.       ptr_reg
  679.         = force_reg (Pmode,
  680.              gen_rtx (LO_SUM, Pmode,
  681.                   tmp_reg, const_part));
  682.     }
  683.       else
  684.     {
  685.       if (! VAL_14_BITS_P (newoffset))
  686.         int_part = force_reg (Pmode, GEN_INT (newoffset));
  687.       else
  688.         int_part = GEN_INT (newoffset);
  689.  
  690.       ptr_reg = force_reg (Pmode,
  691.                    gen_rtx (PLUS, Pmode,
  692.                     force_reg (Pmode, XEXP (x, 0)),
  693.                     int_part));
  694.     }
  695.       return plus_constant (ptr_reg, offset - newoffset);
  696.     }
  697.  
  698.   /* Try to arrange things so that indexing modes can be used, but
  699.      only do so if indexing is safe.
  700.  
  701.      Indexing is safe when the second operand for the outer PLUS
  702.      is a REG, SUBREG, SYMBOL_REF or the like.
  703.  
  704.      For 2.5, indexing is also safe for (plus (symbol_ref) (const_int))
  705.      if the integer is > 0.  */
  706.   if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == MULT
  707.       && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
  708.       && shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1)))
  709.       && (GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == 'o'
  710.       || GET_CODE (XEXP (x, 1)) == SUBREG)
  711.       && GET_CODE (XEXP (x, 1)) != CONST)
  712.     {
  713.       int val = INTVAL (XEXP (XEXP (x, 0), 1));
  714.       rtx reg1, reg2;
  715.       reg1 = force_reg (Pmode, force_operand (XEXP (x, 1), 0));
  716.       reg2 = force_reg (Pmode,
  717.             force_operand (XEXP (XEXP (x, 0), 0), 0));
  718.       return force_reg (Pmode,
  719.                 gen_rtx (PLUS, Pmode,
  720.                  gen_rtx (MULT, Pmode, reg2,
  721.                       GEN_INT (val)),
  722.                  reg1));
  723.     }
  724.  
  725.   /* Uh-oh.  We might have an address for x[n-100000].  This needs
  726.      special handling.  */
  727.  
  728.   if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == MULT
  729.       && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
  730.       && shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1))))
  731.     {
  732.       /* Ugly.  We modify things here so that the address offset specified
  733.      by the index expression is computed first, then added to x to form
  734.      the entire address.
  735.  
  736.      For 2.5, it might be profitable to set things up so that we
  737.      compute the raw (unscaled) index first, then use scaled indexing
  738.      to access memory, or better yet have the MI parts of the compiler
  739.      handle this.  */
  740.  
  741.       rtx regx1, regy1, regy2, y;
  742.  
  743.       /* Strip off any CONST.  */
  744.       y = XEXP (x, 1);
  745.       if (GET_CODE (y) == CONST)
  746.     y = XEXP (y, 0);
  747.  
  748.       if (GET_CODE (y) == PLUS || GET_CODE (y) == MINUS)
  749.     {
  750.       regx1 = force_reg (Pmode, force_operand (XEXP (x, 0), 0));
  751.       regy1 = force_reg (Pmode, force_operand (XEXP (y, 0), 0));
  752.       regy2 = force_reg (Pmode, force_operand (XEXP (y, 1), 0));
  753.       regx1 = force_reg (Pmode, gen_rtx (GET_CODE (y), Pmode, regx1, regy2));
  754.       return force_reg (Pmode, gen_rtx (PLUS, Pmode, regx1, regy1));
  755.     }
  756.     }
  757.  
  758.   return orig;
  759. }
  760.  
  761. /* For the HPPA, REG and REG+CONST is cost 0
  762.    and addresses involving symbolic constants are cost 2.
  763.  
  764.    PIC addresses are very expensive.
  765.  
  766.    It is no coincidence that this has the same structure
  767.    as GO_IF_LEGITIMATE_ADDRESS.  */
  768. int
  769. hppa_address_cost (X)
  770.      rtx X;
  771. {
  772.   if (GET_CODE (X) == PLUS)
  773.       return 1;
  774.   else if (GET_CODE (X) == LO_SUM)
  775.     return 1;
  776.   else if (GET_CODE (X) == HIGH)
  777.     return 2;
  778.   return 4;
  779. }
  780.  
  781. /* Emit insns to move operands[1] into operands[0].
  782.  
  783.    Return 1 if we have written out everything that needs to be done to
  784.    do the move.  Otherwise, return 0 and the caller will emit the move
  785.    normally.  */
  786.  
  787. int
  788. emit_move_sequence (operands, mode, scratch_reg)
  789.      rtx *operands;
  790.      enum machine_mode mode;
  791.      rtx scratch_reg;
  792. {
  793.   register rtx operand0 = operands[0];
  794.   register rtx operand1 = operands[1];
  795.  
  796.   /* Handle secondary reloads for loads/stores of FP registers from
  797.      REG+D addresses where D does not fit in 5 bits, including 
  798.      (subreg (mem (addr)) cases.  */
  799.   if (fp_reg_operand (operand0, mode)
  800.       && ((GET_CODE (operand1) == MEM
  801.        && ! memory_address_p (DFmode, XEXP (operand1, 0)))
  802.       || ((GET_CODE (operand1) == SUBREG
  803.            && GET_CODE (XEXP (operand1, 0)) == MEM
  804.            && !memory_address_p (DFmode, XEXP (XEXP (operand1, 0), 0)))))
  805.       && scratch_reg)
  806.     {
  807.       if (GET_CODE (operand1) == SUBREG)
  808.     operand1 = XEXP (operand1, 0);
  809.  
  810.       scratch_reg = gen_rtx (REG, SImode, REGNO (scratch_reg));
  811.  
  812.       /* D might not fit in 14 bits either; for such cases load D into
  813.      scratch reg.  */
  814.       if (!memory_address_p (SImode, XEXP (operand1, 0)))
  815.     {
  816.       emit_move_insn (scratch_reg, XEXP (XEXP (operand1, 0), 1));
  817.       emit_move_insn (scratch_reg, gen_rtx (GET_CODE (XEXP (operand1, 0)),
  818.                         SImode,
  819.                         XEXP (XEXP (operand1, 0), 0),
  820.                         scratch_reg));
  821.     }
  822.       else
  823.     emit_move_insn (scratch_reg, XEXP (operand1, 0));
  824.       emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (MEM, mode,
  825.                                 scratch_reg)));
  826.       return 1;
  827.     }
  828.   else if (fp_reg_operand (operand1, mode)
  829.        && ((GET_CODE (operand0) == MEM
  830.         && ! memory_address_p (DFmode, XEXP (operand0, 0)))
  831.            || ((GET_CODE (operand0) == SUBREG)
  832.            && GET_CODE (XEXP (operand0, 0)) == MEM
  833.            && !memory_address_p (DFmode, XEXP (XEXP (operand0, 0), 0))))
  834.        && scratch_reg)
  835.     {
  836.       if (GET_CODE (operand0) == SUBREG)
  837.     operand0 = XEXP (operand0, 0);
  838.  
  839.       scratch_reg = gen_rtx (REG, SImode, REGNO (scratch_reg));
  840.       /* D might not fit in 14 bits either; for such cases load D into
  841.      scratch reg.  */
  842.       if (!memory_address_p (SImode, XEXP (operand0, 0)))
  843.     {
  844.       emit_move_insn (scratch_reg, XEXP (XEXP (operand0, 0), 1));
  845.       emit_move_insn (scratch_reg, gen_rtx (GET_CODE (XEXP (operand0, 0)),
  846.                         SImode,
  847.                         XEXP (XEXP (operand0, 0), 0),
  848.                         scratch_reg));
  849.     }
  850.       else
  851.     emit_move_insn (scratch_reg, XEXP (operand0, 0));
  852.       emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (MEM, mode, scratch_reg),
  853.               operand1));
  854.       return 1;
  855.     }
  856.   /* Handle secondary reloads for loads of FP registers from constant
  857.      expressions by forcing the constant into memory.
  858.  
  859.      use scratch_reg to hold the address of the memory location.
  860.  
  861.      ??? The proper fix is to change PREFERRED_RELOAD_CLASS to return
  862.      NO_REGS when presented with a const_int and an register class
  863.      containing only FP registers.  Doing so unfortunately creates
  864.      more problems than it solves.   Fix this for 2.5.  */
  865.   else if (fp_reg_operand (operand0, mode)
  866.        && CONSTANT_P (operand1)
  867.        && scratch_reg)
  868.     {
  869.       rtx xoperands[2];
  870.  
  871.       /* Force the constant into memory and put the address of the
  872.      memory location into scratch_reg.  */
  873.       xoperands[0] = scratch_reg;
  874.       xoperands[1] = XEXP (force_const_mem (mode, operand1), 0);
  875.       emit_move_sequence (xoperands, Pmode, 0);
  876.  
  877.       /* Now load the destination register.  */
  878.       emit_insn (gen_rtx (SET, mode, operand0,
  879.               gen_rtx (MEM, mode, scratch_reg)));
  880.       return 1;
  881.     }
  882.   /* Handle secondary reloads for SAR.  These occur when trying to load
  883.      the SAR from memory a FP register, or with a constant.  */
  884.   else if (GET_CODE (operand0) == REG
  885.        && REGNO_REG_CLASS (REGNO (operand0)) == SHIFT_REGS
  886.        && (GET_CODE (operand1) == MEM
  887.            || GET_CODE (operand1) == CONST_INT
  888.            || (GET_CODE (operand1) == REG
  889.            && FP_REG_CLASS_P (REGNO_REG_CLASS (REGNO (operand1)))))
  890.        && scratch_reg)
  891.     {
  892.       emit_move_insn (scratch_reg, operand1);
  893.       emit_move_insn (operand0, scratch_reg);
  894.       return 1;
  895.     }
  896.   /* Handle most common case: storing into a register.  */
  897.   else if (register_operand (operand0, mode))
  898.     {
  899.       if (register_operand (operand1, mode)
  900.       || (GET_CODE (operand1) == CONST_INT && INT_14_BITS (operand1))
  901.       || (operand1 == CONST0_RTX (mode))
  902.       || (GET_CODE (operand1) == HIGH
  903.           && !symbolic_operand (XEXP (operand1, 0), VOIDmode))
  904.       /* Only `general_operands' can come here, so MEM is ok.  */
  905.       || GET_CODE (operand1) == MEM)
  906.     {
  907.       /* Run this case quickly.  */
  908.       emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1));
  909.       return 1;
  910.     }
  911.     }
  912.   else if (GET_CODE (operand0) == MEM)
  913.     {
  914.       if (register_operand (operand1, mode) || operand1 == CONST0_RTX (mode))
  915.     {
  916.       /* Run this case quickly.  */
  917.       emit_insn (gen_rtx (SET, VOIDmode, operand0, operand1));
  918.       return 1;
  919.     }
  920.       if (! (reload_in_progress || reload_completed))
  921.     {
  922.       operands[0] = validize_mem (operand0);
  923.       operands[1] = operand1 = force_reg (mode, operand1);
  924.     }
  925.     }
  926.  
  927.   /* Simplify the source if we need to.  */
  928.   if ((GET_CODE (operand1) != HIGH && immediate_operand (operand1, mode))
  929.       || (GET_CODE (operand1) == HIGH
  930.       && symbolic_operand (XEXP (operand1, 0), mode)))
  931.     {
  932.       int ishighonly = 0;
  933.  
  934.       if (GET_CODE (operand1) == HIGH)
  935.     {
  936.       ishighonly = 1;
  937.       operand1 = XEXP (operand1, 0);
  938.     }
  939.       if (symbolic_operand (operand1, mode))
  940.     {
  941.       rtx const_part = NULL;
  942.  
  943.       /* Argh.  The assembler and linker can't handle arithmetic
  944.          involving plabels.  We'll have to split up operand1 here
  945.          if it's a function label involved in an arithmetic
  946.          expression.  Luckily, this only happens with addition
  947.          of constants to plabels, which simplifies the test.
  948.  
  949.          We add the constant back in just before returning to
  950.          our caller.  */
  951.       if (GET_CODE (operand1) == CONST
  952.           && GET_CODE (XEXP (operand1, 0)) == PLUS
  953.           && function_label_operand (XEXP (XEXP (operand1, 0), 0), Pmode))
  954.         {
  955.           /* Save away the constant part of the expression.  */
  956.           const_part = XEXP (XEXP (operand1, 0), 1);
  957.           if (GET_CODE (const_part) != CONST_INT)
  958.         abort ();
  959.  
  960.           /* Set operand1 to just the SYMBOL_REF.  */
  961.           operand1 = XEXP (XEXP (operand1, 0), 0);
  962.         }
  963.  
  964.       if (flag_pic)
  965.         {
  966.           rtx temp;
  967.  
  968.           if (reload_in_progress || reload_completed)
  969.         temp = scratch_reg ? scratch_reg : operand0;
  970.           else
  971.         temp = gen_reg_rtx (Pmode);
  972.  
  973.           /* If operand1 is a function label, then we've got to
  974.          force it to memory, then load op0 from memory.  */
  975.           if (function_label_operand (operand1, mode))
  976.         {
  977.           operands[1] = force_const_mem (mode, operand1);
  978.           emit_move_sequence (operands, mode, temp);
  979.         }
  980.           /* Likewise for (const (plus (symbol) (const_int)) when generating
  981.          pic code during or after reload and const_int will not fit
  982.          in 14 bits.  */
  983.           else if (GET_CODE (operand1) == CONST
  984.                && GET_CODE (XEXP (operand1, 0)) == PLUS
  985.                && GET_CODE (XEXP (XEXP (operand1, 0), 1)) == CONST_INT
  986.                && !INT_14_BITS (XEXP (XEXP (operand1, 0), 1))
  987.                && (reload_completed || reload_in_progress)
  988.                && flag_pic)
  989.         {
  990.           operands[1] = force_const_mem (mode, operand1);
  991.           operands[1] = legitimize_pic_address (XEXP (operands[1], 0),
  992.                             mode, temp);
  993.           emit_move_sequence (operands, mode, temp);
  994.         }
  995.           else
  996.         {
  997.           operands[1] = legitimize_pic_address (operand1, mode, temp);
  998.           emit_insn (gen_rtx (SET, VOIDmode, operand0, operands[1]));
  999.         }
  1000.         }
  1001.       /* On the HPPA, references to data space are supposed to use dp,
  1002.          register 27, but showing it in the RTL inhibits various cse
  1003.          and loop optimizations.  */
  1004.       else
  1005.         {
  1006.           rtx temp, set;
  1007.  
  1008.           if (reload_in_progress || reload_completed)
  1009.         temp = scratch_reg ? scratch_reg : operand0;
  1010.           else
  1011.         temp = gen_reg_rtx (mode);
  1012.  
  1013.           if (ishighonly)
  1014.         set = gen_rtx (SET, mode, operand0, temp);
  1015.           else
  1016.         set = gen_rtx (SET, VOIDmode,
  1017.                    operand0,
  1018.                    gen_rtx (LO_SUM, mode, temp, operand1));
  1019.  
  1020.           emit_insn (gen_rtx (SET, VOIDmode,
  1021.                   temp,
  1022.                   gen_rtx (HIGH, mode, operand1)));
  1023.           emit_insn (set);
  1024.  
  1025.         }
  1026.  
  1027.       /* Add back in the constant part if needed.  */
  1028.       if (const_part != NULL)
  1029.         expand_inc (operand0, const_part);
  1030.       return 1;
  1031.     }
  1032.       else if (GET_CODE (operand1) != CONST_INT
  1033.            || ! cint_ok_for_move (INTVAL (operand1)))
  1034.     {
  1035.       rtx temp;
  1036.  
  1037.       if (reload_in_progress || reload_completed)
  1038.         temp = operand0;
  1039.       else
  1040.         temp = gen_reg_rtx (mode);
  1041.  
  1042.       emit_insn (gen_rtx (SET, VOIDmode, temp,
  1043.                   gen_rtx (HIGH, mode, operand1)));
  1044.       operands[1] = gen_rtx (LO_SUM, mode, temp, operand1);
  1045.     }
  1046.     }
  1047.   /* Now have insn-emit do whatever it normally does.  */
  1048.   return 0;
  1049. }
  1050.  
  1051. /* Does operand (which is a symbolic_operand) live in text space? If
  1052.    so SYMBOL_REF_FLAG, which is set by ENCODE_SECTION_INFO, will be true.  */
  1053.  
  1054. int
  1055. read_only_operand (operand)
  1056.      rtx operand;
  1057. {
  1058.   if (GET_CODE (operand) == CONST)
  1059.     operand = XEXP (XEXP (operand, 0), 0);
  1060.   if (flag_pic)
  1061.     {
  1062.       if (GET_CODE (operand) == SYMBOL_REF)
  1063.     return SYMBOL_REF_FLAG (operand) && !CONSTANT_POOL_ADDRESS_P (operand);
  1064.     }
  1065.   else
  1066.     {
  1067.       if (GET_CODE (operand) == SYMBOL_REF)
  1068.     return SYMBOL_REF_FLAG (operand) || CONSTANT_POOL_ADDRESS_P (operand);
  1069.     }
  1070.   return 1;
  1071. }
  1072.  
  1073.  
  1074. /* Return the best assembler insn template
  1075.    for moving operands[1] into operands[0] as a fullword.   */
  1076. char *
  1077. singlemove_string (operands)
  1078.      rtx *operands;
  1079. {
  1080.   HOST_WIDE_INT intval;
  1081.  
  1082.   if (GET_CODE (operands[0]) == MEM)
  1083.     return "stw %r1,%0";
  1084.   if (GET_CODE (operands[1]) == MEM)
  1085.     return "ldw %1,%0";
  1086.   if (GET_CODE (operands[1]) == CONST_DOUBLE)
  1087.     {
  1088.       long i;
  1089.       REAL_VALUE_TYPE d;
  1090.  
  1091.       if (GET_MODE (operands[1]) != SFmode)
  1092.     abort ();
  1093.  
  1094.       /* Translate the CONST_DOUBLE to a CONST_INT with the same target
  1095.      bit pattern.  */
  1096.       REAL_VALUE_FROM_CONST_DOUBLE (d, operands[1]);
  1097.       REAL_VALUE_TO_TARGET_SINGLE (d, i);
  1098.  
  1099.       operands[1] = GEN_INT (i);
  1100.       /* Fall through to CONST_INT case.  */
  1101.     }
  1102.   if (GET_CODE (operands[1]) == CONST_INT)
  1103.     {
  1104.       intval = INTVAL (operands[1]);
  1105.  
  1106.       if (VAL_14_BITS_P (intval))
  1107.     return "ldi %1,%0";
  1108.       else if ((intval & 0x7ff) == 0)
  1109.     return "ldil L'%1,%0";
  1110.       else if (zdepi_cint_p (intval))
  1111.     return "zdepi %Z1,%0";
  1112.       else
  1113.     return "ldil L'%1,%0\n\tldo R'%1(%0),%0";
  1114.     }
  1115.   return "copy %1,%0";
  1116. }
  1117.  
  1118.  
  1119. /* Compute position (in OP[1]) and width (in OP[2])
  1120.    useful for copying IMM to a register using the zdepi
  1121.    instructions.  Store the immediate value to insert in OP[0].  */
  1122. void
  1123. compute_zdepi_operands (imm, op)
  1124.      unsigned HOST_WIDE_INT imm;
  1125.      unsigned *op;
  1126. {
  1127.   int lsb, len;
  1128.  
  1129.   /* Find the least significant set bit in IMM.  */
  1130.   for (lsb = 0; lsb < 32; lsb++)
  1131.     {
  1132.       if ((imm & 1) != 0)
  1133.         break;
  1134.       imm >>= 1;
  1135.     }
  1136.  
  1137.   /* Choose variants based on *sign* of the 5-bit field.  */
  1138.   if ((imm & 0x10) == 0)
  1139.     len = (lsb <= 28) ? 4 : 32 - lsb;
  1140.   else
  1141.     {
  1142.       /* Find the width of the bitstring in IMM.  */
  1143.       for (len = 5; len < 32; len++)
  1144.     {
  1145.       if ((imm & (1 << len)) == 0)
  1146.         break;
  1147.     }
  1148.  
  1149.       /* Sign extend IMM as a 5-bit value.  */
  1150.       imm = (imm & 0xf) - 0x10;
  1151.     }
  1152.  
  1153.   op[0] = imm;
  1154.   op[1] = 31 - lsb;
  1155.   op[2] = len;
  1156. }
  1157.  
  1158. /* Output assembler code to perform a doubleword move insn
  1159.    with operands OPERANDS.  */
  1160.  
  1161. char *
  1162. output_move_double (operands)
  1163.      rtx *operands;
  1164. {
  1165.   enum { REGOP, OFFSOP, MEMOP, CNSTOP, RNDOP } optype0, optype1;
  1166.   rtx latehalf[2];
  1167.   rtx addreg0 = 0, addreg1 = 0;
  1168.  
  1169.   /* First classify both operands.  */
  1170.  
  1171.   if (REG_P (operands[0]))
  1172.     optype0 = REGOP;
  1173.   else if (offsettable_memref_p (operands[0]))
  1174.     optype0 = OFFSOP;
  1175.   else if (GET_CODE (operands[0]) == MEM)
  1176.     optype0 = MEMOP;
  1177.   else
  1178.     optype0 = RNDOP;
  1179.  
  1180.   if (REG_P (operands[1]))
  1181.     optype1 = REGOP;
  1182.   else if (CONSTANT_P (operands[1]))
  1183.     optype1 = CNSTOP;
  1184.   else if (offsettable_memref_p (operands[1]))
  1185.     optype1 = OFFSOP;
  1186.   else if (GET_CODE (operands[1]) == MEM)
  1187.     optype1 = MEMOP;
  1188.   else
  1189.     optype1 = RNDOP;
  1190.  
  1191.   /* Check for the cases that the operand constraints are not
  1192.      supposed to allow to happen.  Abort if we get one,
  1193.      because generating code for these cases is painful.  */
  1194.  
  1195.   if (optype0 != REGOP && optype1 != REGOP)
  1196.     abort ();
  1197.  
  1198.    /* Handle auto decrementing and incrementing loads and stores
  1199.      specifically, since the structure of the function doesn't work
  1200.      for them without major modification.  Do it better when we learn
  1201.      this port about the general inc/dec addressing of PA.
  1202.      (This was written by tege.  Chide him if it doesn't work.)  */
  1203.  
  1204.   if (optype0 == MEMOP)
  1205.     {
  1206.       /* We have to output the address syntax ourselves, since print_operand
  1207.      doesn't deal with the addresses we want to use.  Fix this later.  */
  1208.  
  1209.       rtx addr = XEXP (operands[0], 0);
  1210.       if (GET_CODE (addr) == POST_INC || GET_CODE (addr) == POST_DEC)
  1211.     {
  1212.       rtx high_reg = gen_rtx (SUBREG, SImode, operands[1], 0);
  1213.  
  1214.       operands[0] = XEXP (addr, 0);
  1215.       if (GET_CODE (operands[1]) != REG || GET_CODE (operands[0]) != REG)
  1216.         abort ();
  1217.  
  1218.       if (!reg_overlap_mentioned_p (high_reg, addr))
  1219.         {
  1220.           /* No overlap between high target register and address
  1221.          register.  (We do this in a non-obvious way to
  1222.          save a register file writeback)  */
  1223.           if (GET_CODE (addr) == POST_INC)
  1224.         return "stws,ma %1,8(0,%0)\n\tstw %R1,-4(0,%0)";
  1225.           return "stws,ma %1,-8(0,%0)\n\tstw %R1,12(0,%0)";
  1226.         }
  1227.       else
  1228.         abort();
  1229.     }
  1230.       else if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
  1231.     {
  1232.       rtx high_reg = gen_rtx (SUBREG, SImode, operands[1], 0);
  1233.  
  1234.       operands[0] = XEXP (addr, 0);
  1235.       if (GET_CODE (operands[1]) != REG || GET_CODE (operands[0]) != REG)
  1236.         abort ();
  1237.  
  1238.       if (!reg_overlap_mentioned_p (high_reg, addr))
  1239.         {
  1240.           /* No overlap between high target register and address
  1241.          register.  (We do this in a non-obvious way to
  1242.          save a register file writeback)  */
  1243.           if (GET_CODE (addr) == PRE_INC)
  1244.         return "stws,mb %1,8(0,%0)\n\tstw %R1,4(0,%0)";
  1245.           return "stws,mb %1,-8(0,%0)\n\tstw %R1,4(0,%0)";
  1246.         }
  1247.       else
  1248.         abort();
  1249.     }
  1250.     }
  1251.   if (optype1 == MEMOP)
  1252.     {
  1253.       /* We have to output the address syntax ourselves, since print_operand
  1254.      doesn't deal with the addresses we want to use.  Fix this later.  */
  1255.  
  1256.       rtx addr = XEXP (operands[1], 0);
  1257.       if (GET_CODE (addr) == POST_INC || GET_CODE (addr) == POST_DEC)
  1258.     {
  1259.       rtx high_reg = gen_rtx (SUBREG, SImode, operands[0], 0);
  1260.  
  1261.       operands[1] = XEXP (addr, 0);
  1262.       if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG)
  1263.         abort ();
  1264.  
  1265.       if (!reg_overlap_mentioned_p (high_reg, addr))
  1266.         {
  1267.           /* No overlap between high target register and address
  1268.          register.  (We do this in a non-obvious way to
  1269.          save a register file writeback)  */
  1270.           if (GET_CODE (addr) == POST_INC)
  1271.         return "ldws,ma 8(0,%1),%0\n\tldw -4(0,%1),%R0";
  1272.           return "ldws,ma -8(0,%1),%0\n\tldw 12(0,%1),%R0";
  1273.         }
  1274.       else
  1275.         {
  1276.           /* This is an undefined situation.  We should load into the
  1277.          address register *and* update that register.  Probably
  1278.          we don't need to handle this at all.  */
  1279.           if (GET_CODE (addr) == POST_INC)
  1280.         return "ldw 4(0,%1),%R0\n\tldws,ma 8(0,%1),%0";
  1281.           return "ldw 4(0,%1),%R0\n\tldws,ma -8(0,%1),%0";
  1282.         }
  1283.     }
  1284.       else if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
  1285.     {
  1286.       rtx high_reg = gen_rtx (SUBREG, SImode, operands[0], 0);
  1287.  
  1288.       operands[1] = XEXP (addr, 0);
  1289.       if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG)
  1290.         abort ();
  1291.  
  1292.       if (!reg_overlap_mentioned_p (high_reg, addr))
  1293.         {
  1294.           /* No overlap between high target register and address
  1295.          register.  (We do this in a non-obvious way to
  1296.          save a register file writeback)  */
  1297.           if (GET_CODE (addr) == PRE_INC)
  1298.         return "ldws,mb 8(0,%1),%0\n\tldw 4(0,%1),%R0";
  1299.           return "ldws,mb -8(0,%1),%0\n\tldw 4(0,%1),%R0";
  1300.         }
  1301.       else
  1302.         {
  1303.           /* This is an undefined situation.  We should load into the
  1304.          address register *and* update that register.  Probably
  1305.          we don't need to handle this at all.  */
  1306.           if (GET_CODE (addr) == PRE_INC)
  1307.         return "ldw 12(0,%1),%R0\n\tldws,mb 8(0,%1),%0";
  1308.           return "ldw -4(0,%1),%R0\n\tldws,mb -8(0,%1),%0";
  1309.         }
  1310.     }
  1311.     }
  1312.  
  1313.   /* If an operand is an unoffsettable memory ref, find a register
  1314.      we can increment temporarily to make it refer to the second word.  */
  1315.  
  1316.   if (optype0 == MEMOP)
  1317.     addreg0 = find_addr_reg (XEXP (operands[0], 0));
  1318.  
  1319.   if (optype1 == MEMOP)
  1320.     addreg1 = find_addr_reg (XEXP (operands[1], 0));
  1321.  
  1322.   /* Ok, we can do one word at a time.
  1323.      Normally we do the low-numbered word first.
  1324.  
  1325.      In either case, set up in LATEHALF the operands to use
  1326.      for the high-numbered word and in some cases alter the
  1327.      operands in OPERANDS to be suitable for the low-numbered word.  */
  1328.  
  1329.   if (optype0 == REGOP)
  1330.     latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  1331.   else if (optype0 == OFFSOP)
  1332.     latehalf[0] = adj_offsettable_operand (operands[0], 4);
  1333.   else
  1334.     latehalf[0] = operands[0];
  1335.  
  1336.   if (optype1 == REGOP)
  1337.     latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
  1338.   else if (optype1 == OFFSOP)
  1339.     latehalf[1] = adj_offsettable_operand (operands[1], 4);
  1340.   else if (optype1 == CNSTOP)
  1341.     split_double (operands[1], &operands[1], &latehalf[1]);
  1342.   else
  1343.     latehalf[1] = operands[1];
  1344.  
  1345.   /* If the first move would clobber the source of the second one,
  1346.      do them in the other order.
  1347.  
  1348.      RMS says "This happens only for registers;
  1349.      such overlap can't happen in memory unless the user explicitly
  1350.      sets it up, and that is an undefined circumstance."
  1351.  
  1352.      but it happens on the HP-PA when loading parameter registers,
  1353.      so I am going to define that circumstance, and make it work
  1354.      as expected.  */
  1355.  
  1356.   if (optype0 == REGOP && (optype1 == MEMOP || optype1 == OFFSOP)
  1357.        && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
  1358.     {
  1359.       /* XXX THIS PROBABLY DOESN'T WORK.  */
  1360.       /* Do the late half first.  */
  1361.       if (addreg1)
  1362.     output_asm_insn ("ldo 4(%0),%0", &addreg1);
  1363.       output_asm_insn (singlemove_string (latehalf), latehalf);
  1364.       if (addreg1)
  1365.     output_asm_insn ("ldo -4(%0),%0", &addreg1);
  1366.       /* Then clobber.  */
  1367.       return singlemove_string (operands);
  1368.     }
  1369.  
  1370.   if (optype0 == REGOP && optype1 == REGOP
  1371.       && REGNO (operands[0]) == REGNO (operands[1]) + 1)
  1372.     {
  1373.       output_asm_insn (singlemove_string (latehalf), latehalf);
  1374.       return singlemove_string (operands);
  1375.     }
  1376.  
  1377.   /* Normal case: do the two words, low-numbered first.  */
  1378.  
  1379.   output_asm_insn (singlemove_string (operands), operands);
  1380.  
  1381.   /* Make any unoffsettable addresses point at high-numbered word.  */
  1382.   if (addreg0)
  1383.     output_asm_insn ("ldo 4(%0),%0", &addreg0);
  1384.   if (addreg1)
  1385.     output_asm_insn ("ldo 4(%0),%0", &addreg1);
  1386.  
  1387.   /* Do that word.  */
  1388.   output_asm_insn (singlemove_string (latehalf), latehalf);
  1389.  
  1390.   /* Undo the adds we just did.  */
  1391.   if (addreg0)
  1392.     output_asm_insn ("ldo -4(%0),%0", &addreg0);
  1393.   if (addreg1)
  1394.     output_asm_insn ("ldo -4(%0),%0", &addreg1);
  1395.  
  1396.   return "";
  1397. }
  1398.  
  1399. char *
  1400. output_fp_move_double (operands)
  1401.      rtx *operands;
  1402. {
  1403.   if (FP_REG_P (operands[0]))
  1404.     {
  1405.       if (FP_REG_P (operands[1])
  1406.       || operands[1] == CONST0_RTX (GET_MODE (operands[0])))
  1407.     output_asm_insn ("fcpy,dbl %r1,%0", operands);
  1408.       else
  1409.     output_asm_insn ("fldds%F1 %1,%0", operands);
  1410.     }
  1411.   else if (FP_REG_P (operands[1]))
  1412.     {
  1413.       output_asm_insn ("fstds%F0 %1,%0", operands);
  1414.     }
  1415.   else if (operands[1] == CONST0_RTX (GET_MODE (operands[0])))
  1416.     {
  1417.       if (GET_CODE (operands[0]) == REG)
  1418.     {
  1419.       rtx xoperands[2];
  1420.       xoperands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
  1421.       xoperands[0] = operands[0];
  1422.       output_asm_insn ("copy %%r0,%0\n\tcopy %%r0,%1", xoperands);
  1423.     }
  1424.       /* This is a pain.  You have to be prepared to deal with an
  1425.      arbitrary address here including pre/post increment/decrement.
  1426.  
  1427.      so avoid this in the MD.  */
  1428.       else
  1429.     abort ();
  1430.     }
  1431.   else abort ();
  1432.   return "";
  1433. }
  1434.  
  1435. /* Return a REG that occurs in ADDR with coefficient 1.
  1436.    ADDR can be effectively incremented by incrementing REG.  */
  1437.  
  1438. static rtx
  1439. find_addr_reg (addr)
  1440.      rtx addr;
  1441. {
  1442.   while (GET_CODE (addr) == PLUS)
  1443.     {
  1444.       if (GET_CODE (XEXP (addr, 0)) == REG)
  1445.     addr = XEXP (addr, 0);
  1446.       else if (GET_CODE (XEXP (addr, 1)) == REG)
  1447.     addr = XEXP (addr, 1);
  1448.       else if (CONSTANT_P (XEXP (addr, 0)))
  1449.     addr = XEXP (addr, 1);
  1450.       else if (CONSTANT_P (XEXP (addr, 1)))
  1451.     addr = XEXP (addr, 0);
  1452.       else
  1453.     abort ();
  1454.     }
  1455.   if (GET_CODE (addr) == REG)
  1456.     return addr;
  1457.   abort ();
  1458. }
  1459.  
  1460. /* Emit code to perform a block move.
  1461.  
  1462.    Restriction: If the length argument is non-constant, alignment
  1463.    must be 4.
  1464.  
  1465.    OPERANDS[0] is the destination pointer as a REG, clobbered.
  1466.    OPERANDS[1] is the source pointer as a REG, clobbered.
  1467.    if SIZE_IS_CONSTANT
  1468.      OPERANDS[2] is a register for temporary storage.
  1469.      OPERANDS[4] is the size as a CONST_INT
  1470.    else
  1471.      OPERANDS[2] is a REG which will contain the size, clobbered.
  1472.    OPERANDS[3] is a register for temporary storage.
  1473.    OPERANDS[5] is the alignment safe to use, as a CONST_INT.  */
  1474.  
  1475. char *
  1476. output_block_move (operands, size_is_constant)
  1477.      rtx *operands;
  1478.      int size_is_constant;
  1479. {
  1480.   int align = INTVAL (operands[5]);
  1481.   unsigned long n_bytes;
  1482.  
  1483.   /* We can't move more than four bytes at a time because the PA
  1484.      has no longer integer move insns.  (Could use fp mem ops?)  */
  1485.   if (align > 4)
  1486.     align = 4;
  1487.  
  1488.   if (size_is_constant)
  1489.     {
  1490.       unsigned long offset;
  1491.       rtx temp;
  1492.  
  1493.       n_bytes = INTVAL (operands[4]);
  1494.       if (n_bytes == 0)
  1495.     return "";
  1496.  
  1497.       if (align >= 4)
  1498.     {
  1499.       /* Don't unroll too large blocks.  */
  1500.       if (n_bytes > 32)
  1501.         goto copy_with_loop;
  1502.  
  1503.       /* Read and store using two registers, and hide latency
  1504.          by deferring the stores until three instructions after
  1505.          the corresponding load.  The last load insn will read
  1506.          the entire word were the last bytes are, possibly past
  1507.          the end of the source block, but since loads are aligned,
  1508.          this is harmless.  */
  1509.  
  1510.       output_asm_insn ("ldws,ma 4(0,%1),%2", operands);
  1511.  
  1512.       for (offset = 4; offset < n_bytes; offset += 4)
  1513.         {
  1514.           output_asm_insn ("ldws,ma 4(0,%1),%3", operands);
  1515.           output_asm_insn ("stws,ma %2,4(0,%0)", operands);
  1516.  
  1517.           temp = operands[2];
  1518.           operands[2] = operands[3];
  1519.           operands[3] = temp;
  1520.         }
  1521.       if (n_bytes % 4 == 0)
  1522.         /* Store the last word.  */
  1523.         output_asm_insn ("stw %2,0(0,%0)", operands);
  1524.       else
  1525.         {
  1526.           /* Store the last, partial word.  */
  1527.           operands[4] = GEN_INT (n_bytes % 4);
  1528.           output_asm_insn ("stbys,e %2,%4(0,%0)", operands);
  1529.         }
  1530.       return "";
  1531.     }
  1532.  
  1533.       if (align >= 2 && n_bytes >= 2)
  1534.     {
  1535.       output_asm_insn ("ldhs,ma 2(0,%1),%2", operands);
  1536.  
  1537.       for (offset = 2; offset + 2 <= n_bytes; offset += 2)
  1538.         {
  1539.           output_asm_insn ("ldhs,ma 2(0,%1),%3", operands);
  1540.           output_asm_insn ("sths,ma %2,2(0,%0)", operands);
  1541.  
  1542.           temp = operands[2];
  1543.           operands[2] = operands[3];
  1544.           operands[3] = temp;
  1545.         }
  1546.       if (n_bytes % 2 != 0)
  1547.         output_asm_insn ("ldb 0(0,%1),%3", operands);
  1548.  
  1549.       output_asm_insn ("sths,ma %2,2(0,%0)", operands);
  1550.  
  1551.       if (n_bytes % 2 != 0)
  1552.         output_asm_insn ("stb %3,0(0,%0)", operands);
  1553.  
  1554.       return "";
  1555.     }
  1556.  
  1557.       output_asm_insn ("ldbs,ma 1(0,%1),%2", operands);
  1558.  
  1559.       for (offset = 1; offset + 1 <= n_bytes; offset += 1)
  1560.     {
  1561.       output_asm_insn ("ldbs,ma 1(0,%1),%3", operands);
  1562.       output_asm_insn ("stbs,ma %2,1(0,%0)", operands);
  1563.  
  1564.       temp = operands[2];
  1565.       operands[2] = operands[3];
  1566.       operands[3] = temp;
  1567.     }
  1568.       output_asm_insn ("stb %2,0(0,%0)", operands);
  1569.  
  1570.       return "";
  1571.     }
  1572.  
  1573.   if (align != 4)
  1574.     abort();
  1575.  
  1576.  copy_with_loop:
  1577.  
  1578.   if (size_is_constant)
  1579.     {
  1580.       /* Size is compile-time determined, and also not
  1581.      very small (such small cases are handled above).  */
  1582.       operands[4] = GEN_INT (n_bytes - 4);
  1583.       output_asm_insn ("ldo %4(0),%2", operands);
  1584.     }
  1585.   else
  1586.     {
  1587.       /* Decrement counter by 4, and if it becomes negative, jump past the
  1588.      word copying loop.  */
  1589.       output_asm_insn ("addib,<,n -4,%2,.+16", operands);
  1590.     }
  1591.  
  1592.   /* Copying loop.  Note that the first load is in the annulled delay slot
  1593.      of addib.  Is it OK on PA to have a load in a delay slot, i.e. is a
  1594.      possible page fault stopped in time?  */
  1595.   output_asm_insn ("ldws,ma 4(0,%1),%3", operands);
  1596.   output_asm_insn ("addib,>= -4,%2,.-4", operands);
  1597.   output_asm_insn ("stws,ma %3,4(0,%0)", operands);
  1598.  
  1599.   /* The counter is negative, >= -4.  The remaining number of bytes are
  1600.      determined by the two least significant bits.  */
  1601.  
  1602.   if (size_is_constant)
  1603.     {
  1604.       if (n_bytes % 4 != 0)
  1605.     {
  1606.       /* Read the entire word of the source block tail.  */
  1607.       output_asm_insn ("ldw 0(0,%1),%3", operands);
  1608.       operands[4] = GEN_INT (n_bytes % 4);
  1609.       output_asm_insn ("stbys,e %3,%4(0,%0)", operands);
  1610.     }
  1611.     }
  1612.   else
  1613.     {
  1614.       /* Add 4 to counter.  If it becomes zero, we're done.  */
  1615.       output_asm_insn ("addib,=,n 4,%2,.+16", operands);
  1616.  
  1617.       /* Read the entire word of the source block tail.  (Also this
  1618.      load is in an annulled delay slot.)  */
  1619.       output_asm_insn ("ldw 0(0,%1),%3", operands);
  1620.  
  1621.       /* Make %0 point at the first byte after the destination block.  */
  1622.       output_asm_insn ("addl %2,%0,%0", operands);
  1623.       /* Store the leftmost bytes, up to, but not including, the address
  1624.      in %0.  */
  1625.       output_asm_insn ("stbys,e %3,0(0,%0)", operands);
  1626.     }
  1627.   return "";
  1628. }
  1629.  
  1630. /* Count the number of insns necessary to handle this block move.
  1631.  
  1632.    Basic structure is the same as emit_block_move, except that we
  1633.    count insns rather than emit them.  */
  1634.  
  1635. int
  1636. compute_movstrsi_length (insn)
  1637.      rtx insn;
  1638. {
  1639.   rtx pat = PATTERN (insn);
  1640.   int size_is_constant;
  1641.   int align = INTVAL (XEXP (XVECEXP (pat, 0, 6), 0));
  1642.   unsigned long n_bytes;
  1643.   int insn_count = 0;
  1644.  
  1645.   if (GET_CODE (XEXP (XVECEXP (pat, 0, 5), 0)) == CONST_INT)
  1646.     {
  1647.       size_is_constant = 1;
  1648.       n_bytes = INTVAL (XEXP (XVECEXP (pat, 0, 5), 0));
  1649.     }
  1650.   else
  1651.     {
  1652.       size_is_constant = 0;
  1653.       n_bytes = 0;
  1654.     }
  1655.  
  1656.   /* We can't move more than four bytes at a time because the PA
  1657.      has no longer integer move insns.  (Could use fp mem ops?)  */
  1658.   if (align > 4)
  1659.     align = 4;
  1660.  
  1661.   if (size_is_constant)
  1662.     {
  1663.       unsigned long offset;
  1664.  
  1665.       if (n_bytes == 0)
  1666.     return 0;
  1667.  
  1668.       if (align >= 4)
  1669.     {
  1670.       /* Don't unroll too large blocks.  */
  1671.       if (n_bytes > 32)
  1672.         goto copy_with_loop;
  1673.  
  1674.       /* first load */
  1675.       insn_count = 1;
  1676.  
  1677.       /* Count the unrolled insns.  */
  1678.       for (offset = 4; offset < n_bytes; offset += 4)
  1679.         insn_count += 2;
  1680.  
  1681.       /* Count last store or partial store.  */
  1682.       insn_count += 1;
  1683.       return insn_count * 4;
  1684.     }
  1685.  
  1686.       if (align >= 2 && n_bytes >= 2)
  1687.     {
  1688.       /* initial load.  */
  1689.       insn_count = 1;
  1690.  
  1691.       /* Unrolled loop.  */
  1692.       for (offset = 2; offset + 2 <= n_bytes; offset += 2)
  1693.         insn_count += 2;
  1694.  
  1695.       /* ??? odd load/store */
  1696.       if (n_bytes % 2 != 0)
  1697.         insn_count += 2;
  1698.  
  1699.       /* ??? final store from loop.  */
  1700.       insn_count += 1;
  1701.  
  1702.       return insn_count * 4;
  1703.     }
  1704.  
  1705.       /* First load.  */
  1706.       insn_count = 1;
  1707.  
  1708.       /* The unrolled loop.  */
  1709.       for (offset = 1; offset + 1 <= n_bytes; offset += 1)
  1710.     insn_count += 2;
  1711.  
  1712.       /* Final store.  */
  1713.       insn_count += 1;
  1714.  
  1715.       return insn_count * 4;
  1716.     }
  1717.  
  1718.   if (align != 4)
  1719.     abort();
  1720.  
  1721.  copy_with_loop:
  1722.  
  1723.   /* setup for constant and non-constant case.  */
  1724.   insn_count = 1;
  1725.  
  1726.   /* The copying loop.  */
  1727.   insn_count += 3;
  1728.  
  1729.   /* The counter is negative, >= -4.  The remaining number of bytes are
  1730.      determined by the two least significant bits.  */
  1731.  
  1732.   if (size_is_constant)
  1733.     {
  1734.       if (n_bytes % 4 != 0)
  1735.     insn_count += 2;
  1736.     }
  1737.   else
  1738.     insn_count += 4;
  1739.   return insn_count * 4;
  1740. }
  1741.  
  1742.  
  1743. char *
  1744. output_and (operands)
  1745.      rtx *operands;
  1746. {
  1747.   if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
  1748.     {
  1749.       unsigned HOST_WIDE_INT mask = INTVAL (operands[2]);
  1750.       int ls0, ls1, ms0, p, len;
  1751.  
  1752.       for (ls0 = 0; ls0 < 32; ls0++)
  1753.     if ((mask & (1 << ls0)) == 0)
  1754.       break;
  1755.  
  1756.       for (ls1 = ls0; ls1 < 32; ls1++)
  1757.     if ((mask & (1 << ls1)) != 0)
  1758.       break;
  1759.  
  1760.       for (ms0 = ls1; ms0 < 32; ms0++)
  1761.     if ((mask & (1 << ms0)) == 0)
  1762.       break;
  1763.  
  1764.       if (ms0 != 32)
  1765.     abort();
  1766.  
  1767.       if (ls1 == 32)
  1768.     {
  1769.       len = ls0;
  1770.  
  1771.       if (len == 0)
  1772.         abort ();
  1773.  
  1774.       operands[2] = GEN_INT (len);
  1775.       return "extru %1,31,%2,%0";
  1776.     }
  1777.       else
  1778.     {
  1779.       /* We could use this `depi' for the case above as well, but `depi'
  1780.          requires one more register file access than an `extru'.  */
  1781.  
  1782.       p = 31 - ls0;
  1783.       len = ls1 - ls0;
  1784.  
  1785.       operands[2] = GEN_INT (p);
  1786.       operands[3] = GEN_INT (len);
  1787.       return "depi 0,%2,%3,%0";
  1788.     }
  1789.     }
  1790.   else
  1791.     return "and %1,%2,%0";
  1792. }
  1793.  
  1794. char *
  1795. output_ior (operands)
  1796.      rtx *operands;
  1797. {
  1798.   unsigned HOST_WIDE_INT mask = INTVAL (operands[2]);
  1799.   int bs0, bs1, p, len;
  1800.  
  1801.   if (INTVAL (operands[2]) == 0)
  1802.     return "copy %1,%0";
  1803.  
  1804.   for (bs0 = 0; bs0 < 32; bs0++)
  1805.     if ((mask & (1 << bs0)) != 0)
  1806.       break;
  1807.  
  1808.   for (bs1 = bs0; bs1 < 32; bs1++)
  1809.     if ((mask & (1 << bs1)) == 0)
  1810.       break;
  1811.  
  1812.   if (bs1 != 32 && ((unsigned HOST_WIDE_INT) 1 << bs1) <= mask)
  1813.     abort();
  1814.  
  1815.   p = 31 - bs0;
  1816.   len = bs1 - bs0;
  1817.  
  1818.   operands[2] = GEN_INT (p);
  1819.   operands[3] = GEN_INT (len);
  1820.   return "depi -1,%2,%3,%0";
  1821. }
  1822.  
  1823. /* Output an ascii string.  */
  1824. void
  1825. output_ascii (file, p, size)
  1826.      FILE *file;
  1827.      unsigned char *p;
  1828.      int size;
  1829. {
  1830.   int i;
  1831.   int chars_output;
  1832.   unsigned char partial_output[16];    /* Max space 4 chars can occupy.   */
  1833.  
  1834.   /* The HP assembler can only take strings of 256 characters at one
  1835.      time.  This is a limitation on input line length, *not* the
  1836.      length of the string.  Sigh.  Even worse, it seems that the
  1837.      restriction is in number of input characters (see \xnn &
  1838.      \whatever).  So we have to do this very carefully.  */
  1839.  
  1840.   fprintf (file, "\t.STRING \"");
  1841.  
  1842.   chars_output = 0;
  1843.   for (i = 0; i < size; i += 4)
  1844.     {
  1845.       int co = 0;
  1846.       int io = 0;
  1847.       for (io = 0, co = 0; io < MIN (4, size - i); io++)
  1848.     {
  1849.       register unsigned int c = p[i + io];
  1850.  
  1851.       if (c == '\"' || c == '\\')
  1852.         partial_output[co++] = '\\';
  1853.       if (c >= ' ' && c < 0177)
  1854.         partial_output[co++] = c;
  1855.       else
  1856.         {
  1857.           unsigned int hexd;
  1858.           partial_output[co++] = '\\';
  1859.           partial_output[co++] = 'x';
  1860.           hexd =  c  / 16 - 0 + '0';
  1861.           if (hexd > '9')
  1862.         hexd -= '9' - 'a' + 1;
  1863.           partial_output[co++] = hexd;
  1864.           hexd =  c % 16 - 0 + '0';
  1865.           if (hexd > '9')
  1866.         hexd -= '9' - 'a' + 1;
  1867.           partial_output[co++] = hexd;
  1868.         }
  1869.     }
  1870.       if (chars_output + co > 243)
  1871.     {
  1872.       fprintf (file, "\"\n\t.STRING \"");
  1873.       chars_output = 0;
  1874.     }
  1875.       fwrite (partial_output, 1, co, file);
  1876.       chars_output += co;
  1877.       co = 0;
  1878.     }
  1879.   fprintf (file, "\"\n");
  1880. }
  1881.  
  1882. /* You may have trouble believing this, but this is the HP-PA stack
  1883.    layout.  Wow.
  1884.  
  1885.    Offset        Contents
  1886.  
  1887.    Variable arguments    (optional; any number may be allocated)
  1888.  
  1889.    SP-(4*(N+9))        arg word N
  1890.        :            :
  1891.       SP-56        arg word 5
  1892.       SP-52        arg word 4
  1893.  
  1894.    Fixed arguments    (must be allocated; may remain unused)
  1895.  
  1896.       SP-48        arg word 3
  1897.       SP-44        arg word 2
  1898.       SP-40        arg word 1
  1899.       SP-36        arg word 0
  1900.  
  1901.    Frame Marker
  1902.  
  1903.       SP-32        External Data Pointer (DP)
  1904.       SP-28        External sr4
  1905.       SP-24        External/stub RP (RP')
  1906.       SP-20        Current RP
  1907.       SP-16        Static Link
  1908.       SP-12        Clean up
  1909.       SP-8        Calling Stub RP (RP'')
  1910.       SP-4        Previous SP
  1911.  
  1912.    Top of Frame
  1913.  
  1914.       SP-0        Stack Pointer (points to next available address)
  1915.  
  1916. */
  1917.  
  1918. /* This function saves registers as follows.  Registers marked with ' are
  1919.    this function's registers (as opposed to the previous function's).
  1920.    If a frame_pointer isn't needed, r4 is saved as a general register;
  1921.    the space for the frame pointer is still allocated, though, to keep
  1922.    things simple.
  1923.  
  1924.  
  1925.    Top of Frame
  1926.  
  1927.        SP (FP')        Previous FP
  1928.        SP + 4        Alignment filler (sigh)
  1929.        SP + 8        Space for locals reserved here.
  1930.        .
  1931.        .
  1932.        .
  1933.        SP + n        All call saved register used.
  1934.        .
  1935.        .
  1936.        .
  1937.        SP + o        All call saved fp registers used.
  1938.        .
  1939.        .
  1940.        .
  1941.        SP + p (SP')    points to next available address.
  1942.  
  1943. */
  1944.  
  1945. /* Emit RTL to store REG at the memory location specified by BASE+DISP.
  1946.    Handle case where DISP > 8k by using the add_high_const pattern.
  1947.  
  1948.    Note in DISP > 8k case, we will leave the high part of the address
  1949.    in %r1.  There is code in expand_hppa_{prologue,epilogue} that knows this.*/
  1950. static void
  1951. store_reg (reg, disp, base)
  1952.      int reg, disp, base;
  1953. {
  1954.   if (VAL_14_BITS_P (disp))
  1955.     {
  1956.       emit_move_insn (gen_rtx (MEM, SImode,
  1957.                    gen_rtx (PLUS, SImode,
  1958.                         gen_rtx (REG, SImode, base),
  1959.                         GEN_INT (disp))),
  1960.               gen_rtx (REG, SImode, reg));
  1961.     }
  1962.   else
  1963.     {
  1964.       emit_insn (gen_add_high_const (gen_rtx (REG, SImode, 1),
  1965.                      gen_rtx (REG, SImode, base),
  1966.                      GEN_INT (disp)));
  1967.       emit_move_insn (gen_rtx (MEM, SImode,
  1968.                    gen_rtx (LO_SUM, SImode,
  1969.                     gen_rtx (REG, SImode, 1),
  1970.                     GEN_INT (disp))),
  1971.               gen_rtx (REG, SImode, reg));
  1972.     }
  1973. }
  1974.  
  1975. /* Emit RTL to load REG from the memory location specified by BASE+DISP.
  1976.    Handle case where DISP > 8k by using the add_high_const pattern.
  1977.  
  1978.    Note in DISP > 8k case, we will leave the high part of the address
  1979.    in %r1.  There is code in expand_hppa_{prologue,epilogue} that knows this.*/
  1980. static void
  1981. load_reg (reg, disp, base)
  1982.      int reg, disp, base;
  1983. {
  1984.   if (VAL_14_BITS_P (disp))
  1985.     {
  1986.       emit_move_insn (gen_rtx (REG, SImode, reg),
  1987.               gen_rtx (MEM, SImode,
  1988.                    gen_rtx (PLUS, SImode,
  1989.                         gen_rtx (REG, SImode, base),
  1990.                         GEN_INT (disp))));
  1991.     }
  1992.   else
  1993.     {
  1994.       emit_insn (gen_add_high_const (gen_rtx (REG, SImode, 1),
  1995.                      gen_rtx (REG, SImode, base),
  1996.                      GEN_INT (disp)));
  1997.       emit_move_insn (gen_rtx (REG, SImode, reg),
  1998.               gen_rtx (MEM, SImode,
  1999.                    gen_rtx (LO_SUM, SImode,
  2000.                     gen_rtx (REG, SImode, 1),
  2001.                     GEN_INT (disp))));
  2002.     }
  2003. }
  2004.  
  2005. /* Emit RTL to set REG to the value specified by BASE+DISP.
  2006.    Handle case where DISP > 8k by using the add_high_const pattern.
  2007.  
  2008.    Note in DISP > 8k case, we will leave the high part of the address
  2009.    in %r1.  There is code in expand_hppa_{prologue,epilogue} that knows this.*/
  2010. static void
  2011. set_reg_plus_d(reg, base, disp)
  2012.      int reg, base, disp;
  2013. {
  2014.   if (VAL_14_BITS_P (disp))
  2015.     {
  2016.       emit_move_insn (gen_rtx (REG, SImode, reg),
  2017.               gen_rtx (PLUS, SImode,
  2018.                    gen_rtx (REG, SImode, base),
  2019.                    GEN_INT (disp)));
  2020.     }
  2021.   else
  2022.     {
  2023.       emit_insn (gen_add_high_const (gen_rtx (REG, SImode, 1),
  2024.                      gen_rtx (REG, SImode, base),
  2025.                      GEN_INT (disp)));
  2026.       emit_move_insn (gen_rtx (REG, SImode, reg),
  2027.               gen_rtx (LO_SUM, SImode,
  2028.                     gen_rtx (REG, SImode, 1),
  2029.                     GEN_INT (disp)));
  2030.     }
  2031. }
  2032.  
  2033. /* Global variables set by FUNCTION_PROLOGUE.  */
  2034. /* Size of frame.  Need to know this to emit return insns from
  2035.    leaf procedures.  */
  2036. static int actual_fsize;
  2037. static int local_fsize, save_fregs;
  2038.  
  2039. int
  2040. compute_frame_size (size, fregs_live)
  2041.      int size;
  2042.      int *fregs_live;
  2043. {
  2044.   extern int current_function_outgoing_args_size;
  2045.   int i, fsize;
  2046.  
  2047.   /* 8 is space for frame pointer + filler. If any frame is allocated
  2048.      we need to add this in because of STARTING_FRAME_OFFSET. */
  2049.   fsize = size + (size || frame_pointer_needed ? 8 : 0);
  2050.  
  2051.   for (i = 18; i >= 4; i--)
  2052.     {
  2053.       if (regs_ever_live[i])
  2054.     fsize += 4;
  2055.     }
  2056.   /* If we don't have a frame pointer, the register normally used for that
  2057.      purpose is saved just like other registers, not in the "frame marker".  */
  2058.   if (! frame_pointer_needed)
  2059.     {
  2060.       if (regs_ever_live[FRAME_POINTER_REGNUM])
  2061.     fsize += 4;
  2062.     }
  2063.   fsize = (fsize + 7) & ~7;
  2064.  
  2065.   for (i = 66; i >= 48; i -= 2)
  2066.     if (regs_ever_live[i] || regs_ever_live[i + 1])
  2067.       {
  2068.     fsize += 8;
  2069.     if (fregs_live)
  2070.       *fregs_live = 1;
  2071.       }
  2072.  
  2073.   fsize += current_function_outgoing_args_size;
  2074.   if (! leaf_function_p () || fsize)
  2075.     fsize += 32;
  2076.   return (fsize + 63) & ~63;
  2077. }
  2078.  
  2079. rtx hp_profile_label_rtx;
  2080. static char hp_profile_label_name[8];
  2081. void
  2082. output_function_prologue (file, size)
  2083.      FILE *file;
  2084.      int size;
  2085. {
  2086.   /* The function's label and associated .PROC must never be
  2087.      separated and must be output *after* any profiling declarations
  2088.      to avoid changing spaces/subspaces within a procedure.  */
  2089.   ASM_OUTPUT_LABEL (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
  2090.   fputs ("\t.PROC\n", file);
  2091.  
  2092.   /* hppa_expand_prologue does the dirty work now.  We just need
  2093.      to output the assembler directives which denote the start
  2094.      of a function.  */
  2095.   fprintf (file, "\t.CALLINFO FRAME=%d", actual_fsize);
  2096.   if (regs_ever_live[2] || profile_flag)
  2097.     fprintf (file, ",CALLS,SAVE_RP");
  2098.   else
  2099.     fprintf (file, ",NO_CALLS");
  2100.  
  2101.   if (frame_pointer_needed)
  2102.     fprintf (file, ",SAVE_SP");
  2103.  
  2104.   /* Pass on information about the number of callee register saves
  2105.      performed in the prologue.
  2106.  
  2107.      The compiler is supposed to pass the highest register number
  2108.      saved, the assembler then has to adjust that number before
  2109.      entering it into the unwind descriptor (to account for any
  2110.      caller saved registers with lower register numbers than the
  2111.      first callee saved register).  */
  2112.   if (gr_saved)
  2113.     fprintf (file, ",ENTRY_GR=%d", gr_saved + 2);
  2114.  
  2115.   if (fr_saved)
  2116.     fprintf (file, ",ENTRY_FR=%d", fr_saved + 11);
  2117.  
  2118.   fprintf (file, "\n\t.ENTRY\n");
  2119.  
  2120.   /* Horrid hack.  emit_function_prologue will modify this RTL in
  2121.      place to get the expected results.  */
  2122.   if (profile_flag)
  2123.     ASM_GENERATE_INTERNAL_LABEL (hp_profile_label_name, "LP",
  2124.                  hp_profile_labelno);
  2125.  
  2126.   if (insn_addresses)
  2127.     {
  2128.       unsigned int old_total = total_code_bytes;
  2129.  
  2130.       total_code_bytes += insn_addresses[INSN_UID (get_last_insn())];
  2131.       total_code_bytes += FUNCTION_BOUNDARY /BITS_PER_UNIT;
  2132.  
  2133.       /* Be prepared to handle overflows.  */
  2134.       total_code_bytes = old_total > total_code_bytes ? -1 : total_code_bytes;
  2135.     }
  2136.   else
  2137.     total_code_bytes = -1;
  2138. }
  2139.  
  2140. void
  2141. hppa_expand_prologue()
  2142. {
  2143.   extern char call_used_regs[];
  2144.   int size = get_frame_size ();
  2145.   int merge_sp_adjust_with_store = 0;
  2146.   int i, offset;
  2147.   rtx tmpreg, size_rtx;
  2148.  
  2149.   gr_saved = 0;
  2150.   fr_saved = 0;
  2151.   save_fregs = 0;
  2152.   local_fsize =  size + (size || frame_pointer_needed ? 8 : 0);
  2153.   actual_fsize = compute_frame_size (size, &save_fregs);
  2154.  
  2155.   /* Compute a few things we will use often.  */
  2156.   tmpreg = gen_rtx (REG, SImode, 1);
  2157.   size_rtx = GEN_INT (actual_fsize);
  2158.  
  2159.   /* Save RP first.  The calling conventions manual states RP will
  2160.      always be stored into the caller's frame at sp-20.  */
  2161.   if (regs_ever_live[2] || profile_flag)
  2162.     store_reg (2, -20, STACK_POINTER_REGNUM);
  2163.  
  2164.   /* Allocate the local frame and set up the frame pointer if needed.  */
  2165.   if (actual_fsize)
  2166.     if (frame_pointer_needed)
  2167.       {
  2168.     /* Copy the old frame pointer temporarily into %r1.  Set up the
  2169.        new stack pointer, then store away the saved old frame pointer
  2170.        into the stack at sp+actual_fsize and at the same time update
  2171.        the stack pointer by actual_fsize bytes.  Two versions, first
  2172.        handles small (<8k) frames.  The second handles large (>8k)
  2173.        frames.  */
  2174.     emit_move_insn (tmpreg, frame_pointer_rtx);
  2175.     emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
  2176.     if (VAL_14_BITS_P (actual_fsize))
  2177.       emit_insn (gen_post_stwm (stack_pointer_rtx,
  2178.                     stack_pointer_rtx,
  2179.                     size_rtx, tmpreg));
  2180.     else
  2181.       {
  2182.         /* It is incorrect to store the saved frame pointer at *sp,
  2183.            then increment sp (writes beyond the current stack boundary).
  2184.  
  2185.            So instead use stwm to store at *sp and post-increment the
  2186.            stack pointer as an atomic operation.  Then increment sp to
  2187.            finish allocating the new frame.  */
  2188.         emit_insn (gen_post_stwm (stack_pointer_rtx,
  2189.                       stack_pointer_rtx,
  2190.                       GEN_INT (64), tmpreg));
  2191.         set_reg_plus_d (STACK_POINTER_REGNUM,
  2192.                 STACK_POINTER_REGNUM,
  2193.                 actual_fsize - 64);
  2194.       }
  2195.       }
  2196.     /* no frame pointer needed.  */
  2197.     else
  2198.       {
  2199.     /* In some cases we can perform the first callee register save
  2200.        and allocating the stack frame at the same time.   If so, just
  2201.        make a note of it and defer allocating the frame until saving
  2202.        the callee registers.  */
  2203.     if (VAL_14_BITS_P (-actual_fsize)
  2204.         && local_fsize == 0
  2205.         && ! profile_flag
  2206.         && ! flag_pic)
  2207.       merge_sp_adjust_with_store = 1;
  2208.     /* Can not optimize.  Adjust the stack frame by actual_fsize bytes.  */
  2209.     else if (actual_fsize != 0)
  2210.       set_reg_plus_d (STACK_POINTER_REGNUM,
  2211.               STACK_POINTER_REGNUM,
  2212.               actual_fsize);
  2213.       }
  2214.   /* The hppa calling conventions say that that %r19, the pic offset
  2215.      register, is saved at sp - 32 (in this function's frame)  when
  2216.      generating PIC code.  FIXME:  What is the correct thing to do
  2217.      for functions which make no calls and allocate no frame?  Do
  2218.      we need to allocate a frame, or can we just omit the save?   For
  2219.      now we'll just omit the save.  */
  2220.   if (actual_fsize != 0 && flag_pic)
  2221.     store_reg (PIC_OFFSET_TABLE_REGNUM, -32, STACK_POINTER_REGNUM);
  2222.  
  2223.   /* Profiling code.
  2224.  
  2225.      Instead of taking one argument, the counter label, as most normal
  2226.      mcounts do, _mcount appears to behave differently on the HPPA.  It
  2227.      takes the return address of the caller, the address of this routine,
  2228.      and the address of the label.  Also, it isn't magic, so
  2229.      argument registers have to be preserved.  */
  2230.   if (profile_flag)
  2231.     {
  2232.       int pc_offset, i, arg_offset, basereg, offsetadj;
  2233.  
  2234.       pc_offset = 4 + (frame_pointer_needed
  2235.                ? (VAL_14_BITS_P (actual_fsize) ? 12 : 20)
  2236.                : (VAL_14_BITS_P (actual_fsize) ? 4 : 8));
  2237.  
  2238.       /* When the function has a frame pointer, use it as the base
  2239.      register for saving/restore registers.  Else use the stack
  2240.      pointer.  Adjust the offset according to the frame size if
  2241.      this function does not have a frame pointer.  */
  2242.  
  2243.       basereg = frame_pointer_needed ? FRAME_POINTER_REGNUM
  2244.                      : STACK_POINTER_REGNUM;
  2245.       offsetadj = frame_pointer_needed ? 0 : actual_fsize;
  2246.  
  2247.       /* Horrid hack.  emit_function_prologue will modify this RTL in
  2248.      place to get the expected results.   sprintf here is just to
  2249.      put something in the name.  */
  2250.       sprintf(hp_profile_label_name, "LP$%04d", -1);
  2251.       hp_profile_label_rtx = gen_rtx (SYMBOL_REF, SImode,
  2252.                       hp_profile_label_name);
  2253.       if (current_function_returns_struct)
  2254.     store_reg (STRUCT_VALUE_REGNUM, - 12 - offsetadj, basereg);
  2255.  
  2256.       for (i = 26, arg_offset = -36 - offsetadj; i >= 23; i--, arg_offset -= 4)
  2257.     if (regs_ever_live [i])
  2258.       {
  2259.         store_reg (i, arg_offset, basereg);
  2260.         /* Deal with arg_offset not fitting in 14 bits.  */
  2261.         pc_offset += VAL_14_BITS_P (arg_offset) ? 4 : 8;
  2262.       }
  2263.  
  2264.       emit_move_insn (gen_rtx (REG, SImode, 26), gen_rtx (REG, SImode, 2));
  2265.       emit_move_insn (tmpreg, gen_rtx (HIGH, SImode, hp_profile_label_rtx));
  2266.       emit_move_insn (gen_rtx (REG, SImode, 24),
  2267.               gen_rtx (LO_SUM, SImode, tmpreg, hp_profile_label_rtx));
  2268.       /* %r25 is set from within the output pattern.  */
  2269.       emit_insn (gen_call_profiler (GEN_INT (- pc_offset - 20)));
  2270.  
  2271.       /* Restore argument registers.  */
  2272.       for (i = 26, arg_offset = -36 - offsetadj; i >= 23; i--, arg_offset -= 4)
  2273.     if (regs_ever_live [i])
  2274.       load_reg (i, arg_offset, basereg);
  2275.  
  2276.       if (current_function_returns_struct)
  2277.     load_reg (STRUCT_VALUE_REGNUM, -12 - offsetadj, basereg);
  2278.  
  2279.     }
  2280.  
  2281.   /* Normal register save.
  2282.  
  2283.      Do not save the frame pointer in the frame_pointer_needed case.  It
  2284.      was done earlier.  */
  2285.   if (frame_pointer_needed)
  2286.     {
  2287.       for (i = 18, offset = local_fsize; i >= 4; i--)
  2288.     if (regs_ever_live[i] && ! call_used_regs[i])
  2289.       {
  2290.         store_reg (i, offset, FRAME_POINTER_REGNUM);
  2291.         offset += 4;
  2292.         gr_saved++;
  2293.       }
  2294.       /* Account for %r4 which is saved in a special place.  */
  2295.       gr_saved++;
  2296.     }
  2297.   /* No frame pointer needed.  */
  2298.   else
  2299.     {
  2300.       for (i = 18, offset = local_fsize - actual_fsize; i >= 3; i--)
  2301.           if (regs_ever_live[i] && ! call_used_regs[i])
  2302.       {
  2303.         /* If merge_sp_adjust_with_store is nonzero, then we can
  2304.            optimize the first GR save.  */
  2305.         if (merge_sp_adjust_with_store)
  2306.           {
  2307.         merge_sp_adjust_with_store = 0;
  2308.             emit_insn (gen_post_stwm (stack_pointer_rtx,
  2309.                       stack_pointer_rtx,
  2310.                       GEN_INT (-offset),
  2311.                       gen_rtx (REG, SImode, i)));
  2312.           }
  2313.         else
  2314.           store_reg (i, offset, STACK_POINTER_REGNUM);
  2315.         offset += 4;
  2316.         gr_saved++;
  2317.       }
  2318.  
  2319.       /* If we wanted to merge the SP adjustment with a GR save, but we never
  2320.      did any GR saves, then just emit the adjustment here.  */
  2321.       if (merge_sp_adjust_with_store)
  2322.     set_reg_plus_d (STACK_POINTER_REGNUM,
  2323.             STACK_POINTER_REGNUM,
  2324.             actual_fsize);
  2325.     }
  2326.  
  2327.   /* Align pointer properly (doubleword boundary).  */
  2328.   offset = (offset + 7) & ~7;
  2329.  
  2330.   /* Floating point register store.  */
  2331.   if (save_fregs)
  2332.     {
  2333.  
  2334.       /* First get the frame or stack pointer to the start of the FP register
  2335.      save area.  */
  2336.       if (frame_pointer_needed)
  2337.     set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset);
  2338.       else
  2339.     set_reg_plus_d (1, STACK_POINTER_REGNUM, offset);
  2340.  
  2341.       /* Now actually save the FP registers.  */
  2342.       for (i = 66; i >= 48; i -= 2)
  2343.     if (regs_ever_live[i] || regs_ever_live[i + 1])
  2344.       {
  2345.         emit_move_insn (gen_rtx (MEM, DFmode,
  2346.                      gen_rtx (POST_INC, DFmode, tmpreg)),
  2347.                 gen_rtx (REG, DFmode, i));
  2348.         fr_saved++;
  2349.       }
  2350.     }
  2351. }
  2352.  
  2353.  
  2354. void
  2355. output_function_epilogue (file, size)
  2356.      FILE *file;
  2357.      int size;
  2358. {
  2359.   rtx insn = get_last_insn ();
  2360.   int i;
  2361.  
  2362.   /* hppa_expand_epilogue does the dirty work now.  We just need
  2363.      to output the assembler directives which denote the end
  2364.      of a function.
  2365.  
  2366.      To make debuggers happy, emit a nop if the epilogue was completely
  2367.      eliminated due to a volatile call as the last insn in the
  2368.      current function.  That way the return address (in %r2) will
  2369.      always point to a valid instruction in the current function.  */
  2370.  
  2371.   /* Get the last real insn.  */
  2372.   if (GET_CODE (insn) == NOTE)
  2373.     insn = prev_real_insn (insn);
  2374.  
  2375.   /* If it is a sequence, then look inside.  */
  2376.   if (insn && GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
  2377.     insn = XVECEXP (PATTERN (insn), 0, 0);
  2378.  
  2379.   /* If insn is a CALL_INSN, then it must be a call to a volatile
  2380.      function (otherwise there would be epilogue insns).  */
  2381.   if (insn && GET_CODE (insn) == CALL_INSN)
  2382.     fprintf (file, "\tnop\n");
  2383.  
  2384.   fprintf (file, "\t.EXIT\n\t.PROCEND\n");
  2385.  
  2386.   /* If we have deferred plabels, then we need to switch into the data
  2387.      section and align it to a 4 byte boundary before we output the
  2388.      deferred plabels.  */
  2389.   if (n_deferred_plabels)
  2390.     {
  2391.       data_section ();
  2392.       ASM_OUTPUT_ALIGN (file, 2);
  2393.     }
  2394.  
  2395.   /* Now output the deferred plabels.  */
  2396.   for (i = 0; i < n_deferred_plabels; i++)
  2397.     {
  2398.       ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (deferred_plabels[i].internal_label));
  2399.       ASM_OUTPUT_INT (file, deferred_plabels[i].symbol);
  2400.     }
  2401.   n_deferred_plabels = 0;
  2402. }
  2403.  
  2404. void
  2405. hppa_expand_epilogue ()
  2406. {
  2407.   rtx tmpreg;
  2408.   int offset,i;
  2409.   int merge_sp_adjust_with_load  = 0;
  2410.  
  2411.   /* We will use this often.  */
  2412.   tmpreg = gen_rtx (REG, SImode, 1);
  2413.  
  2414.   /* Try to restore RP early to avoid load/use interlocks when
  2415.      RP gets used in the return (bv) instruction.  This appears to still
  2416.      be necessary even when we schedule the prologue and epilogue. */
  2417.   if (frame_pointer_needed
  2418.       && (regs_ever_live [2] || profile_flag))
  2419.     load_reg (2, -20, FRAME_POINTER_REGNUM);
  2420.  
  2421.   /* No frame pointer, and stack is smaller than 8k.  */
  2422.   else if (! frame_pointer_needed
  2423.        && VAL_14_BITS_P (actual_fsize + 20)
  2424.        && (regs_ever_live[2] || profile_flag))
  2425.     load_reg (2, - (actual_fsize + 20), STACK_POINTER_REGNUM);
  2426.  
  2427.   /* General register restores.  */
  2428.   if (frame_pointer_needed)
  2429.     {
  2430.       for (i = 18, offset = local_fsize; i >= 4; i--)
  2431.     if (regs_ever_live[i] && ! call_used_regs[i])
  2432.       {
  2433.         load_reg (i, offset, FRAME_POINTER_REGNUM);
  2434.         offset += 4;
  2435.       }
  2436.     }
  2437.   else
  2438.     {
  2439.       for (i = 18, offset = local_fsize - actual_fsize; i >= 3; i--)
  2440.     if (regs_ever_live[i] && ! call_used_regs[i])
  2441.       {
  2442.         /* Only for the first load.
  2443.            merge_sp_adjust_with_load holds the register load
  2444.            with which we will merge the sp adjustment.  */
  2445.         if (VAL_14_BITS_P (actual_fsize + 20)
  2446.         && local_fsize == 0
  2447.         && ! merge_sp_adjust_with_load)
  2448.           merge_sp_adjust_with_load = i;
  2449.         else
  2450.           load_reg (i, offset, STACK_POINTER_REGNUM);
  2451.         offset += 4;
  2452.       }
  2453.     }
  2454.  
  2455.   /* Align pointer properly (doubleword boundary).  */
  2456.   offset = (offset + 7) & ~7;
  2457.  
  2458.   /* FP register restores.  */
  2459.   if (save_fregs)
  2460.     {
  2461.       /* Adjust the register to index off of.  */
  2462.       if (frame_pointer_needed)
  2463.     set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset);
  2464.       else
  2465.     set_reg_plus_d (1, STACK_POINTER_REGNUM, offset);
  2466.  
  2467.       /* Actually do the restores now.  */
  2468.       for (i = 66; i >= 48; i -= 2)
  2469.     if (regs_ever_live[i] || regs_ever_live[i + 1])
  2470.       emit_move_insn (gen_rtx (REG, DFmode, i),
  2471.               gen_rtx (MEM, DFmode,
  2472.                    gen_rtx (POST_INC, DFmode, tmpreg)));
  2473.     }
  2474.  
  2475.   /* No frame pointer, but we have a stack greater than 8k.  We restore
  2476.      %r2 very late in this case.  (All other cases are restored as early
  2477.      as possible.)  */
  2478.   if (! frame_pointer_needed
  2479.       && ! VAL_14_BITS_P (actual_fsize + 20)
  2480.       && (regs_ever_live[2] || profile_flag))
  2481.     {
  2482.       set_reg_plus_d (STACK_POINTER_REGNUM,
  2483.               STACK_POINTER_REGNUM,
  2484.               - actual_fsize);
  2485.  
  2486.       /* This used to try and be clever by not depending on the value in
  2487.      %r30 and instead use the value held in %r1 (so that the 2nd insn
  2488.      which sets %r30 could be put in the delay slot of the return insn).
  2489.     
  2490.      That won't work since if the stack is exactly 8k set_reg_plus_d
  2491.      doesn't set %r1, just %r30.  */
  2492.       load_reg (2, - 20, STACK_POINTER_REGNUM);
  2493.     }
  2494.  
  2495.   /* Reset stack pointer (and possibly frame pointer).  The stack */
  2496.   /* pointer is initially set to fp + 64 to avoid a race condition.
  2497.      ??? What race condition?!?  */
  2498.   else if (frame_pointer_needed)
  2499.     {
  2500.       /* Emit a blockage insn here to keep these insns from being moved
  2501.      to the beginning of the prologue or into the main instruction
  2502.      stream, doing so avoids some very obscure problems.  */
  2503.       emit_insn (gen_blockage ());
  2504.       set_reg_plus_d (STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, 64);
  2505.       emit_insn (gen_pre_ldwm (stack_pointer_rtx, stack_pointer_rtx,
  2506.                    GEN_INT (-64), frame_pointer_rtx));
  2507.     }
  2508.   /* If we were deferring a callee register restore, do it now.  */
  2509.   else if (! frame_pointer_needed  && merge_sp_adjust_with_load)
  2510.     emit_insn (gen_pre_ldwm (stack_pointer_rtx,
  2511.                  stack_pointer_rtx,
  2512.                  GEN_INT (- actual_fsize),
  2513.                  gen_rtx (REG, SImode,
  2514.                  merge_sp_adjust_with_load)));
  2515.   else if (actual_fsize != 0)
  2516.     set_reg_plus_d (STACK_POINTER_REGNUM,
  2517.             STACK_POINTER_REGNUM,
  2518.             - actual_fsize);
  2519. }
  2520.  
  2521. /* This is only valid once reload has completed because it depends on
  2522.    knowing exactly how much (if any) frame there is and...
  2523.  
  2524.    It's only valid if there is no frame marker to de-allocate and...
  2525.  
  2526.    It's only valid if %r2 hasn't been saved into the caller's frame
  2527.    (we're not profiling and %r2 isn't live anywhere).  */
  2528. int
  2529. hppa_can_use_return_insn_p ()
  2530. {
  2531.   return (reload_completed
  2532.       && (compute_frame_size (get_frame_size (), 0) ? 0 : 1)
  2533.       && ! profile_flag
  2534.       && ! regs_ever_live[2]
  2535.       && ! frame_pointer_needed);
  2536. }
  2537.  
  2538. void
  2539. emit_bcond_fp (code, operand0)
  2540.      enum rtx_code code;
  2541.      rtx operand0;
  2542. {
  2543.   emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
  2544.                gen_rtx (IF_THEN_ELSE, VOIDmode,
  2545.                     gen_rtx (code, VOIDmode,
  2546.                          gen_rtx (REG, CCFPmode, 0),
  2547.                          const0_rtx),
  2548.                     gen_rtx (LABEL_REF, VOIDmode, operand0),
  2549.                     pc_rtx)));
  2550.  
  2551. }
  2552.  
  2553. rtx
  2554. gen_cmp_fp (code, operand0, operand1)
  2555.      enum rtx_code code;
  2556.      rtx operand0, operand1;
  2557. {
  2558.   return gen_rtx (SET, VOIDmode, gen_rtx (REG, CCFPmode, 0),
  2559.           gen_rtx (code, CCFPmode, operand0, operand1));
  2560. }
  2561.  
  2562. /* Adjust the cost of a scheduling dependency.  Return the new cost of
  2563.    a dependency LINK or INSN on DEP_INSN.  COST is the current cost.  */
  2564.  
  2565. int
  2566. pa_adjust_cost (insn, link, dep_insn, cost)
  2567.      rtx insn;
  2568.      rtx link;
  2569.      rtx dep_insn;
  2570.      int cost;
  2571. {
  2572.   if (! recog_memoized (insn))
  2573.     return 0;
  2574.  
  2575.   if (REG_NOTE_KIND (link) == 0)
  2576.     {
  2577.       /* Data dependency; DEP_INSN writes a register that INSN reads some
  2578.      cycles later.  */
  2579.  
  2580.       if (get_attr_type (insn) == TYPE_FPSTORE)
  2581.     {
  2582.       rtx pat = PATTERN (insn);
  2583.       rtx dep_pat = PATTERN (dep_insn);
  2584.       if (GET_CODE (pat) == PARALLEL)
  2585.         {
  2586.           /* This happens for the fstXs,mb patterns.  */
  2587.           pat = XVECEXP (pat, 0, 0);
  2588.         }
  2589.       if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
  2590.         /* If this happens, we have to extend this to schedule
  2591.            optimally.  Return 0 for now.  */
  2592.       return 0;
  2593.  
  2594.       if (rtx_equal_p (SET_DEST (dep_pat), SET_SRC (pat)))
  2595.         {
  2596.           if (! recog_memoized (dep_insn))
  2597.         return 0;
  2598.           /* DEP_INSN is writing its result to the register
  2599.          being stored in the fpstore INSN.  */
  2600.           switch (get_attr_type (dep_insn))
  2601.         {
  2602.         case TYPE_FPLOAD:
  2603.           /* This cost 3 cycles, not 2 as the md says for the
  2604.              700 and 7100.  Note scaling of cost for 7100.  */
  2605.           return cost + (pa_cpu_attr == PROCESSOR_700) ? 1 : 2;
  2606.  
  2607.         case TYPE_FPALU:
  2608.         case TYPE_FPMULSGL:
  2609.         case TYPE_FPMULDBL:
  2610.         case TYPE_FPDIVSGL:
  2611.         case TYPE_FPDIVDBL:
  2612.         case TYPE_FPSQRTSGL:
  2613.         case TYPE_FPSQRTDBL:
  2614.           /* In these important cases, we save one cycle compared to
  2615.              when flop instruction feed each other.  */
  2616.           return cost - (pa_cpu_attr == PROCESSOR_700) ? 1 : 2;
  2617.  
  2618.         default:
  2619.           return cost;
  2620.         }
  2621.         }
  2622.     }
  2623.  
  2624.       /* For other data dependencies, the default cost specified in the
  2625.      md is correct.  */
  2626.       return cost;
  2627.     }
  2628.   else if (REG_NOTE_KIND (link) == REG_DEP_ANTI)
  2629.     {
  2630.       /* Anti dependency; DEP_INSN reads a register that INSN writes some
  2631.      cycles later.  */
  2632.  
  2633.       if (get_attr_type (insn) == TYPE_FPLOAD)
  2634.     {
  2635.       rtx pat = PATTERN (insn);
  2636.       rtx dep_pat = PATTERN (dep_insn);
  2637.       if (GET_CODE (pat) == PARALLEL)
  2638.         {
  2639.           /* This happens for the fldXs,mb patterns.  */
  2640.           pat = XVECEXP (pat, 0, 0);
  2641.         }
  2642.       if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
  2643.         /* If this happens, we have to extend this to schedule
  2644.            optimally.  Return 0 for now.  */
  2645.       return 0;
  2646.  
  2647.       if (reg_mentioned_p (SET_DEST (pat), SET_SRC (dep_pat)))
  2648.         {
  2649.           if (! recog_memoized (dep_insn))
  2650.         return 0;
  2651.           switch (get_attr_type (dep_insn))
  2652.         {
  2653.         case TYPE_FPALU:
  2654.         case TYPE_FPMULSGL:
  2655.         case TYPE_FPMULDBL:
  2656.         case TYPE_FPDIVSGL:
  2657.         case TYPE_FPDIVDBL:
  2658.         case TYPE_FPSQRTSGL:
  2659.         case TYPE_FPSQRTDBL:
  2660.           /* A fpload can't be issued until one cycle before a
  2661.              preceding arithmetic operation has finished if
  2662.              the target of the fpload is any of the sources
  2663.              (or destination) of the arithmetic operation.  */
  2664.           return cost - (pa_cpu_attr == PROCESSOR_700) ? 1 : 2;
  2665.  
  2666.         default:
  2667.           return 0;
  2668.         }
  2669.         }
  2670.     }
  2671.       else if (get_attr_type (insn) == TYPE_FPALU)
  2672.     {
  2673.       rtx pat = PATTERN (insn);
  2674.       rtx dep_pat = PATTERN (dep_insn);
  2675.       if (GET_CODE (pat) == PARALLEL)
  2676.         {
  2677.           /* This happens for the fldXs,mb patterns.  */
  2678.           pat = XVECEXP (pat, 0, 0);
  2679.         }
  2680.       if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
  2681.         /* If this happens, we have to extend this to schedule
  2682.            optimally.  Return 0 for now.  */
  2683.       return 0;
  2684.  
  2685.       if (reg_mentioned_p (SET_DEST (pat), SET_SRC (dep_pat)))
  2686.         {
  2687.           if (! recog_memoized (dep_insn))
  2688.         return 0;
  2689.           switch (get_attr_type (dep_insn))
  2690.         {
  2691.         case TYPE_FPDIVSGL:
  2692.         case TYPE_FPDIVDBL:
  2693.         case TYPE_FPSQRTSGL:
  2694.         case TYPE_FPSQRTDBL:
  2695.           /* An ALU flop can't be issued until two cycles before a
  2696.              preceding divide or sqrt operation has finished if
  2697.              the target of the ALU flop is any of the sources
  2698.              (or destination) of the divide or sqrt operation.  */
  2699.           return cost - (pa_cpu_attr == PROCESSOR_700) ? 2 : 4;
  2700.  
  2701.         default:
  2702.           return 0;
  2703.         }
  2704.         }
  2705.     }
  2706.  
  2707.       /* For other anti dependencies, the cost is 0.  */
  2708.       return 0;
  2709.     }
  2710.   else if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
  2711.     {
  2712.       /* Output dependency; DEP_INSN writes a register that INSN writes some
  2713.      cycles later.  */
  2714.       if (get_attr_type (insn) == TYPE_FPLOAD)
  2715.     {
  2716.       rtx pat = PATTERN (insn);
  2717.       rtx dep_pat = PATTERN (dep_insn);
  2718.       if (GET_CODE (pat) == PARALLEL)
  2719.         {
  2720.           /* This happens for the fldXs,mb patterns.  */
  2721.           pat = XVECEXP (pat, 0, 0);
  2722.         }
  2723.       if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
  2724.         /* If this happens, we have to extend this to schedule
  2725.            optimally.  Return 0 for now.  */
  2726.       return 0;
  2727.  
  2728.       if (reg_mentioned_p (SET_DEST (pat), SET_DEST (dep_pat)))
  2729.         {
  2730.           if (! recog_memoized (dep_insn))
  2731.         return 0;
  2732.           switch (get_attr_type (dep_insn))
  2733.         {
  2734.         case TYPE_FPALU:
  2735.         case TYPE_FPMULSGL:
  2736.         case TYPE_FPMULDBL:
  2737.         case TYPE_FPDIVSGL:
  2738.         case TYPE_FPDIVDBL:
  2739.         case TYPE_FPSQRTSGL:
  2740.         case TYPE_FPSQRTDBL:
  2741.           /* A fpload can't be issued until one cycle before a
  2742.              preceding arithmetic operation has finished if
  2743.              the target of the fpload is the destination of the
  2744.              arithmetic operation.  */
  2745.           return cost - (pa_cpu_attr == PROCESSOR_700) ? 1 : 2;
  2746.  
  2747.         default:
  2748.           return 0;
  2749.         }
  2750.         }
  2751.     }
  2752.       else if (get_attr_type (insn) == TYPE_FPALU)
  2753.     {
  2754.       rtx pat = PATTERN (insn);
  2755.       rtx dep_pat = PATTERN (dep_insn);
  2756.       if (GET_CODE (pat) == PARALLEL)
  2757.         {
  2758.           /* This happens for the fldXs,mb patterns.  */
  2759.           pat = XVECEXP (pat, 0, 0);
  2760.         }
  2761.       if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
  2762.         /* If this happens, we have to extend this to schedule
  2763.            optimally.  Return 0 for now.  */
  2764.       return 0;
  2765.  
  2766.       if (reg_mentioned_p (SET_DEST (pat), SET_DEST (dep_pat)))
  2767.         {
  2768.           if (! recog_memoized (dep_insn))
  2769.         return 0;
  2770.           switch (get_attr_type (dep_insn))
  2771.         {
  2772.         case TYPE_FPDIVSGL:
  2773.         case TYPE_FPDIVDBL:
  2774.         case TYPE_FPSQRTSGL:
  2775.         case TYPE_FPSQRTDBL:
  2776.           /* An ALU flop can't be issued until two cycles before a
  2777.              preceding divide or sqrt operation has finished if
  2778.              the target of the ALU flop is also the target of
  2779.              of the divide or sqrt operation.  */
  2780.           return cost - (pa_cpu_attr == PROCESSOR_700) ? 2 : 4;
  2781.  
  2782.         default:
  2783.           return 0;
  2784.         }
  2785.         }
  2786.     }
  2787.  
  2788.       /* For other output dependencies, the cost is 0.  */
  2789.       return 0;
  2790.     }
  2791.   else
  2792.     abort ();
  2793. }
  2794.  
  2795. /* Return any length adjustment needed by INSN which already has its length
  2796.    computed as LENGTH.   Return zero if no adjustment is necessary.
  2797.  
  2798.    For the PA: function calls, millicode calls, and backwards short
  2799.    conditional branches with unfilled delay slots need an adjustment by +1
  2800.    (to account for the NOP which will be inserted into the instruction stream).
  2801.  
  2802.    Also compute the length of an inline block move here as it is too
  2803.    complicated to express as a length attribute in pa.md.  */
  2804. int
  2805. pa_adjust_insn_length (insn, length)
  2806.     rtx insn;
  2807.     int length;
  2808. {
  2809.   rtx pat = PATTERN (insn);
  2810.  
  2811.   /* Call insns which are *not* indirect and have unfilled delay slots.  */
  2812.   if (GET_CODE (insn) == CALL_INSN)
  2813.     {
  2814.  
  2815.       if (GET_CODE (XVECEXP (pat, 0, 0)) == CALL
  2816.       && GET_CODE (XEXP (XEXP (XVECEXP (pat, 0, 0), 0), 0)) == SYMBOL_REF)
  2817.     return 4;
  2818.       else if (GET_CODE (XVECEXP (pat, 0, 0)) == SET
  2819.            && GET_CODE (XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0))
  2820.           == SYMBOL_REF)
  2821.     return 4;
  2822.       else
  2823.     return 0;
  2824.     }
  2825.   /* Jumps inside switch tables which have unfilled delay slots 
  2826.      also need adjustment.  */
  2827.   else if (GET_CODE (insn) == JUMP_INSN
  2828.        && simplejump_p (insn)
  2829.        && GET_MODE (PATTERN (insn)) == DImode)
  2830.     return 4;
  2831.   /* Millicode insn with an unfilled delay slot.  */
  2832.   else if (GET_CODE (insn) == INSN
  2833.        && GET_CODE (pat) != SEQUENCE
  2834.        && GET_CODE (pat) != USE
  2835.        && GET_CODE (pat) != CLOBBER
  2836.        && get_attr_type (insn) == TYPE_MILLI)
  2837.     return 4;
  2838.   /* Block move pattern.  */
  2839.   else if (GET_CODE (insn) == INSN
  2840.        && GET_CODE (pat) == PARALLEL
  2841.        && GET_CODE (XEXP (XVECEXP (pat, 0, 0), 0)) == MEM
  2842.        && GET_CODE (XEXP (XVECEXP (pat, 0, 0), 1)) == MEM
  2843.        && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 0)) == BLKmode
  2844.        && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 1)) == BLKmode)
  2845.     return compute_movstrsi_length (insn) - 4;
  2846.   /* Conditional branch with an unfilled delay slot.  */
  2847.   else if (GET_CODE (insn) == JUMP_INSN && ! simplejump_p (insn))
  2848.     {
  2849.       /* Adjust a short backwards conditional with an unfilled delay slot.  */
  2850.       if (GET_CODE (pat) == SET
  2851.       && length == 4
  2852.       && ! forward_branch_p (insn))
  2853.     return 4;
  2854.       /* Adjust dbra insn with short backwards conditional branch with
  2855.      unfilled delay slot -- only for case where counter is in a
  2856.      general register register. */
  2857.       else if (GET_CODE (pat) == PARALLEL
  2858.            && GET_CODE (XVECEXP (pat, 0, 1)) == SET
  2859.            && GET_CODE (XEXP (XVECEXP (pat, 0, 1), 0)) == REG
  2860.             && ! FP_REG_P (XEXP (XVECEXP (pat, 0, 1), 0))
  2861.            && length == 4
  2862.            && ! forward_branch_p (insn))
  2863.     return 4;
  2864.       else
  2865.     return 0;
  2866.     }
  2867.   else
  2868.     return 0;
  2869. }
  2870.  
  2871. /* Print operand X (an rtx) in assembler syntax to file FILE.
  2872.    CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
  2873.    For `%' followed by punctuation, CODE is the punctuation and X is null.  */
  2874.  
  2875. void
  2876. print_operand (file, x, code)
  2877.      FILE *file;
  2878.      rtx x;
  2879.      int code;
  2880. {
  2881.   switch (code)
  2882.     {
  2883.     case '#':
  2884.       /* Output a 'nop' if there's nothing for the delay slot.  */
  2885.       if (dbr_sequence_length () == 0)
  2886.     fputs ("\n\tnop", file);
  2887.       return;
  2888.     case '*':
  2889.       /* Output an nullification completer if there's nothing for the */
  2890.       /* delay slot or nullification is requested.  */
  2891.       if (dbr_sequence_length () == 0 ||
  2892.       (final_sequence &&
  2893.        INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence, 0, 0))))
  2894.         fputs (",n", file);
  2895.       return;
  2896.     case 'R':
  2897.       /* Print out the second register name of a register pair.
  2898.      I.e., R (6) => 7.  */
  2899.       fputs (reg_names[REGNO (x)+1], file);
  2900.       return;
  2901.     case 'r':
  2902.       /* A register or zero. */
  2903.       if (x == const0_rtx
  2904.       || (x == CONST0_RTX (DFmode))
  2905.       || (x == CONST0_RTX (SFmode)))
  2906.     {
  2907.       fputs ("0", file);
  2908.       return;
  2909.     }
  2910.       else
  2911.     break;
  2912.     case 'C':            /* Plain (C)ondition */
  2913.     case 'X':
  2914.       switch (GET_CODE (x))
  2915.     {
  2916.     case EQ:
  2917.       fprintf (file, "=");  break;
  2918.     case NE:
  2919.       fprintf (file, "<>");  break;
  2920.     case GT:
  2921.       fprintf (file, ">");  break;
  2922.     case GE:
  2923.       fprintf (file, ">=");  break;
  2924.     case GEU:
  2925.       fprintf (file, ">>=");  break;
  2926.     case GTU:
  2927.       fprintf (file, ">>");  break;
  2928.     case LT:
  2929.       fprintf (file, "<");  break;
  2930.     case LE:
  2931.       fprintf (file, "<=");  break;
  2932.     case LEU:
  2933.       fprintf (file, "<<=");  break;
  2934.     case LTU:
  2935.       fprintf (file, "<<");  break;
  2936.     default:
  2937.       abort ();
  2938.     }
  2939.       return;
  2940.     case 'N':            /* Condition, (N)egated */
  2941.       switch (GET_CODE (x))
  2942.     {
  2943.     case EQ:
  2944.       fprintf (file, "<>");  break;
  2945.     case NE:
  2946.       fprintf (file, "=");  break;
  2947.     case GT:
  2948.       fprintf (file, "<=");  break;
  2949.     case GE:
  2950.       fprintf (file, "<");  break;
  2951.     case GEU:
  2952.       fprintf (file, "<<");  break;
  2953.     case GTU:
  2954.       fprintf (file, "<<=");  break;
  2955.     case LT:
  2956.       fprintf (file, ">=");  break;
  2957.     case LE:
  2958.       fprintf (file, ">");  break;
  2959.     case LEU:
  2960.       fprintf (file, ">>");  break;
  2961.     case LTU:
  2962.       fprintf (file, ">>=");  break;
  2963.     default:
  2964.       abort ();
  2965.     }
  2966.       return;
  2967.     /* For floating point comparisons.  Need special conditions to deal
  2968.        with NaNs properly.  */
  2969.     case 'Y':
  2970.       switch (GET_CODE (x))
  2971.     {
  2972.     case EQ:
  2973.       fprintf (file, "!=");  break;
  2974.     case NE:
  2975.       fprintf (file, "=");  break;
  2976.     case GT:
  2977.       fprintf (file, "!>");  break;
  2978.     case GE:
  2979.       fprintf (file, "!>=");  break;
  2980.     case LT:
  2981.       fprintf (file, "!<");  break;
  2982.     case LE:
  2983.       fprintf (file, "!<=");  break;
  2984.     default:
  2985.       abort ();
  2986.     }
  2987.       return;
  2988.     case 'S':            /* Condition, operands are (S)wapped.  */
  2989.       switch (GET_CODE (x))
  2990.     {
  2991.     case EQ:
  2992.       fprintf (file, "=");  break;
  2993.     case NE:
  2994.       fprintf (file, "<>");  break;
  2995.     case GT:
  2996.       fprintf (file, "<");  break;
  2997.     case GE:
  2998.       fprintf (file, "<=");  break;
  2999.     case GEU:
  3000.       fprintf (file, "<<=");  break;
  3001.     case GTU:
  3002.       fprintf (file, "<<");  break;
  3003.     case LT:
  3004.       fprintf (file, ">");  break;
  3005.     case LE:
  3006.       fprintf (file, ">=");  break;
  3007.     case LEU:
  3008.       fprintf (file, ">>=");  break;
  3009.     case LTU:
  3010.       fprintf (file, ">>");  break;
  3011.     default:
  3012.       abort ();
  3013.     }
  3014.       return;
  3015.     case 'B':            /* Condition, (B)oth swapped and negate.  */
  3016.       switch (GET_CODE (x))
  3017.     {
  3018.     case EQ:
  3019.       fprintf (file, "<>");  break;
  3020.     case NE:
  3021.       fprintf (file, "=");  break;
  3022.     case GT:
  3023.       fprintf (file, ">=");  break;
  3024.     case GE:
  3025.       fprintf (file, ">");  break;
  3026.     case GEU:
  3027.       fprintf (file, ">>");  break;
  3028.     case GTU:
  3029.       fprintf (file, ">>=");  break;
  3030.     case LT:
  3031.       fprintf (file, "<=");  break;
  3032.     case LE:
  3033.       fprintf (file, "<");  break;
  3034.     case LEU:
  3035.       fprintf (file, "<<");  break;
  3036.     case LTU:
  3037.       fprintf (file, "<<=");  break;
  3038.     default:
  3039.       abort ();
  3040.     }
  3041.       return;
  3042.     case 'k':
  3043.       if (GET_CODE (x) == CONST_INT)
  3044.     {
  3045.       fprintf (file, "%d", ~INTVAL (x));
  3046.       return;
  3047.     }
  3048.       abort();
  3049.     case 'L':
  3050.       if (GET_CODE (x) == CONST_INT)
  3051.     {
  3052.       fprintf (file, "%d", 32 - (INTVAL (x) & 31));
  3053.       return;
  3054.     }
  3055.       abort();
  3056.     case 'O':
  3057.       if (GET_CODE (x) == CONST_INT && exact_log2 (INTVAL (x)) >= 0)
  3058.     {
  3059.       fprintf (file, "%d", exact_log2 (INTVAL (x)));
  3060.       return;
  3061.     }
  3062.       abort();
  3063.     case 'P':
  3064.       if (GET_CODE (x) == CONST_INT)
  3065.     {
  3066.       fprintf (file, "%d", 31 - (INTVAL (x) & 31));
  3067.       return;
  3068.     }
  3069.       abort();
  3070.     case 'I':
  3071.       if (GET_CODE (x) == CONST_INT)
  3072.     fputs ("i", file);
  3073.       return;
  3074.     case 'M':
  3075.       switch (GET_CODE (XEXP (x, 0)))
  3076.     {
  3077.     case PRE_DEC:
  3078.     case PRE_INC:
  3079.       fprintf (file, "s,mb");
  3080.       break;
  3081.     case POST_DEC:
  3082.     case POST_INC:
  3083.       fprintf (file, "s,ma");
  3084.       break;
  3085.     default:
  3086.       break;
  3087.     }
  3088.       return;
  3089.     case 'F':
  3090.       switch (GET_CODE (XEXP (x, 0)))
  3091.     {
  3092.     case PRE_DEC:
  3093.     case PRE_INC:
  3094.       fprintf (file, ",mb");
  3095.       break;
  3096.     case POST_DEC:
  3097.     case POST_INC:
  3098.       fprintf (file, ",ma");
  3099.       break;
  3100.     default:
  3101.       break;
  3102.     }
  3103.       return;
  3104.     case 'G':
  3105.       output_global_address (file, x);
  3106.       return;
  3107.     case 0:            /* Don't do anything special */
  3108.       break;
  3109.     case 'Z':
  3110.       {
  3111.     unsigned op[3];
  3112.     compute_zdepi_operands (INTVAL (x), op);
  3113.     fprintf (file, "%d,%d,%d", op[0], op[1], op[2]);
  3114.     return;
  3115.       }
  3116.     default:
  3117.       abort ();
  3118.     }
  3119.   if (GET_CODE (x) == REG)
  3120.     {
  3121.       if (FP_REG_P (x) && GET_MODE_SIZE (GET_MODE (x)) <= 4 && (REGNO (x) & 1) == 0)
  3122.     fprintf (file, "%sL", reg_names [REGNO (x)]);
  3123.       else
  3124.     fprintf (file, "%s", reg_names [REGNO (x)]);
  3125.     }
  3126.   else if (GET_CODE (x) == MEM)
  3127.     {
  3128.       int size = GET_MODE_SIZE (GET_MODE (x));
  3129.       rtx base = XEXP (XEXP (x, 0), 0);
  3130.       switch (GET_CODE (XEXP (x, 0)))
  3131.     {
  3132.     case PRE_DEC:
  3133.     case POST_DEC:
  3134.       fprintf (file, "-%d(0,%s)", size, reg_names [REGNO (base)]);
  3135.       break;
  3136.     case PRE_INC:
  3137.     case POST_INC:
  3138.       fprintf (file, "%d(0,%s)", size, reg_names [REGNO (base)]);
  3139.       break;
  3140.     default:
  3141.       output_address (XEXP (x, 0));
  3142.       break;
  3143.     }
  3144.     }
  3145. #if 0
  3146.   /* The code here is completely wrong.  It attempts to extract parts of
  3147.      a CONST_DOUBLE which is wrong since REAL_ARITHMETIC is defined, and it
  3148.      extracts the wrong indices (0 instead of 2 and 1 instead of 3) using
  3149.      the wrong macro (XINT instead of XWINT).
  3150.      Just disable it for now, since the code will never be used anyway!  */
  3151.   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
  3152.     {
  3153.       union { double d; int i[2]; } u;
  3154.       union { float f; int i; } u1;
  3155.       u.i[0] = XINT (x, 0); u.i[1] = XINT (x, 1);
  3156.       u1.f = u.d;
  3157.       if (code == 'f')
  3158.     fprintf (file, "0r%.9g", u1.f);
  3159.       else
  3160.     fprintf (file, "0x%x", u1.i);
  3161.     }
  3162.   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != VOIDmode)
  3163.     {
  3164.       union { double d; int i[2]; } u;
  3165.       u.i[0] = XINT (x, 0); u.i[1] = XINT (x, 1);
  3166.       fprintf (file, "0r%.20g", u.d);
  3167.     }
  3168. #endif
  3169.   else
  3170.     output_addr_const (file, x);
  3171. }
  3172.  
  3173. /* output a SYMBOL_REF or a CONST expression involving a SYMBOL_REF. */
  3174.  
  3175. void
  3176. output_global_address (file, x)
  3177.      FILE *file;
  3178.      rtx x;
  3179. {
  3180.  
  3181.   /* Imagine  (high (const (plus ...))).  */
  3182.   if (GET_CODE (x) == HIGH)
  3183.     x = XEXP (x, 0);
  3184.  
  3185.   if (GET_CODE (x) == SYMBOL_REF && read_only_operand (x))
  3186.     assemble_name (file, XSTR (x, 0));
  3187.   else if (GET_CODE (x) == SYMBOL_REF && !flag_pic)
  3188.     {
  3189.       assemble_name (file, XSTR (x, 0));
  3190.       fprintf (file, "-$global$");
  3191.     }
  3192.   else if (GET_CODE (x) == CONST)
  3193.     {
  3194.       char *sep = "";
  3195.       int offset = 0;        /* assembler wants -$global$ at end */
  3196.       rtx base;
  3197.  
  3198.       if (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
  3199.     {
  3200.       base = XEXP (XEXP (x, 0), 0);
  3201.       output_addr_const (file, base);
  3202.     }
  3203.       else if (GET_CODE (XEXP (XEXP (x, 0), 0)) == CONST_INT)
  3204.     offset = INTVAL (XEXP (XEXP (x, 0), 0));
  3205.       else abort ();
  3206.  
  3207.       if (GET_CODE (XEXP (XEXP (x, 0), 1)) == SYMBOL_REF)
  3208.     {
  3209.       base = XEXP (XEXP (x, 0), 1);
  3210.       output_addr_const (file, base);
  3211.     }
  3212.       else if (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
  3213.     offset = INTVAL (XEXP (XEXP (x, 0),1));
  3214.       else abort ();
  3215.  
  3216.       if (GET_CODE (XEXP (x, 0)) == PLUS)
  3217.     {
  3218.       if (offset < 0)
  3219.         {
  3220.           offset = -offset;
  3221.           sep = "-";
  3222.         }
  3223.       else
  3224.         sep = "+";
  3225.     }
  3226.       else if (GET_CODE (XEXP (x, 0)) == MINUS
  3227.            && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF))
  3228.     sep = "-";
  3229.       else abort ();
  3230.  
  3231.       if (!read_only_operand (base) && !flag_pic)
  3232.     fprintf (file, "-$global$");
  3233.       fprintf (file, "%s", sep);
  3234.       if (offset) fprintf (file,"%d", offset);
  3235.     }
  3236.   else
  3237.     output_addr_const (file, x);
  3238. }
  3239.  
  3240. /* HP's millicode routines mean something special to the assembler.
  3241.    Keep track of which ones we have used.  */
  3242.  
  3243. enum millicodes { remI, remU, divI, divU, mulI, mulU, end1000 };
  3244. static char imported[(int)end1000];
  3245. static char *milli_names[] = {"remI", "remU", "divI", "divU", "mulI", "mulU"};
  3246. static char import_string[] = ".IMPORT $$....,MILLICODE";
  3247. #define MILLI_START 10
  3248.  
  3249. static void
  3250. import_milli (code)
  3251.      enum millicodes code;
  3252. {
  3253.   char str[sizeof (import_string)];
  3254.  
  3255.   if (!imported[(int)code])
  3256.     {
  3257.       imported[(int)code] = 1;
  3258.       strcpy (str, import_string);
  3259.       strncpy (str + MILLI_START, milli_names[(int)code], 4);
  3260.       output_asm_insn (str, 0);
  3261.     }
  3262. }
  3263.  
  3264. /* The register constraints have put the operands and return value in
  3265.    the proper registers. */
  3266.  
  3267. char *
  3268. output_mul_insn (unsignedp, insn)
  3269.      int unsignedp;
  3270.      rtx insn;
  3271. {
  3272.   import_milli (mulI);
  3273.   return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$mulI"),
  3274.               gen_rtx (REG, SImode, 31));
  3275. }
  3276.  
  3277. /* Emit the rtl for doing a division by a constant. */
  3278.  
  3279. /* Do magic division millicodes exist for this value? */
  3280. static int magic_milli[]= {0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0,
  3281.                  1, 1};
  3282.  
  3283. /* We'll use an array to keep track of the magic millicodes and
  3284.    whether or not we've used them already. [n][0] is signed, [n][1] is
  3285.    unsigned. */
  3286.  
  3287. static int div_milli[16][2];
  3288.  
  3289. int
  3290. div_operand (op, mode)
  3291.      rtx op;
  3292.      enum machine_mode mode;
  3293. {
  3294.   return (mode == SImode
  3295.       && ((GET_CODE (op) == REG && REGNO (op) == 25)
  3296.           || (GET_CODE (op) == CONST_INT && INTVAL (op) > 0
  3297.           && INTVAL (op) < 16 && magic_milli[INTVAL (op)])));
  3298. }
  3299.  
  3300. int
  3301. emit_hpdiv_const (operands, unsignedp)
  3302.      rtx *operands;
  3303.      int unsignedp;
  3304. {
  3305.   if (GET_CODE (operands[2]) == CONST_INT
  3306.       && INTVAL (operands[2]) > 0
  3307.       && INTVAL (operands[2]) < 16
  3308.       && magic_milli[INTVAL (operands[2])])
  3309.     {
  3310.       emit_move_insn ( gen_rtx (REG, SImode, 26), operands[1]);
  3311.       emit
  3312.     (gen_rtx
  3313.      (PARALLEL, VOIDmode,
  3314.       gen_rtvec (5, gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 29),
  3315.                  gen_rtx (unsignedp ? UDIV : DIV, SImode,
  3316.                       gen_rtx (REG, SImode, 26),
  3317.                       operands[2])),
  3318.              gen_rtx (CLOBBER, VOIDmode, operands[3]),
  3319.              gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 26)),
  3320.              gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 25)),
  3321.              gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, 31)))));
  3322.       emit_move_insn (operands[0], gen_rtx (REG, SImode, 29));
  3323.       return 1;
  3324.     }
  3325.   return 0;
  3326. }
  3327.  
  3328. char *
  3329. output_div_insn (operands, unsignedp, insn)
  3330.      rtx *operands;
  3331.      int unsignedp;
  3332.      rtx insn;
  3333. {
  3334.   int divisor;
  3335.  
  3336.   /* If the divisor is a constant, try to use one of the special
  3337.      opcodes .*/
  3338.   if (GET_CODE (operands[0]) == CONST_INT)
  3339.     {
  3340.       static char buf[100];
  3341.       divisor = INTVAL (operands[0]);
  3342.       if (!div_milli[divisor][unsignedp])
  3343.     {
  3344.       div_milli[divisor][unsignedp] = 1;
  3345.       if (unsignedp)
  3346.         output_asm_insn (".IMPORT $$divU_%0,MILLICODE", operands);
  3347.       else
  3348.         output_asm_insn (".IMPORT $$divI_%0,MILLICODE", operands);
  3349.     }
  3350.       if (unsignedp)
  3351.     {
  3352.       sprintf (buf, "$$divU_%d", INTVAL (operands[0]));
  3353.       return output_call (insn, gen_rtx (SYMBOL_REF, SImode, buf),
  3354.                   gen_rtx (REG, SImode, 31));
  3355.     }
  3356.       else
  3357.     {
  3358.       sprintf (buf, "$$divI_%d", INTVAL (operands[0]));
  3359.       return output_call (insn, gen_rtx (SYMBOL_REF, SImode, buf),
  3360.                   gen_rtx (REG, SImode, 31));
  3361.     }
  3362.     }
  3363.   /* Divisor isn't a special constant. */
  3364.   else
  3365.     {
  3366.       if (unsignedp)
  3367.     {
  3368.       import_milli (divU);
  3369.       return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$divU"),
  3370.                   gen_rtx (REG, SImode, 31));
  3371.     }
  3372.       else
  3373.     {
  3374.       import_milli (divI);
  3375.       return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$divI"),
  3376.                   gen_rtx (REG, SImode, 31));
  3377.     }
  3378.     }
  3379. }
  3380.  
  3381. /* Output a $$rem millicode to do mod. */
  3382.  
  3383. char *
  3384. output_mod_insn (unsignedp, insn)
  3385.      int unsignedp;
  3386.      rtx insn;
  3387. {
  3388.   if (unsignedp)
  3389.     {
  3390.       import_milli (remU);
  3391.       return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$remU"),
  3392.               gen_rtx (REG, SImode, 31));
  3393.     }
  3394.   else
  3395.     {
  3396.       import_milli (remI);
  3397.       return output_call (insn, gen_rtx (SYMBOL_REF, SImode, "$$remI"),
  3398.               gen_rtx (REG, SImode, 31));
  3399.     }
  3400. }
  3401.  
  3402. void
  3403. output_arg_descriptor (call_insn)
  3404.      rtx call_insn;
  3405. {
  3406.   char *arg_regs[4];
  3407.   enum machine_mode arg_mode;
  3408.   rtx link;
  3409.   int i, output_flag = 0;
  3410.   int regno;
  3411.  
  3412.   for (i = 0; i < 4; i++)
  3413.     arg_regs[i] = 0;
  3414.  
  3415.   /* Specify explicitly that no argument relocations should take place
  3416.      if using the portable runtime calling conventions.  */
  3417.   if (TARGET_PORTABLE_RUNTIME)
  3418.     {
  3419.       fprintf (asm_out_file,
  3420.            "\t.CALL ARGW0=NO,ARGW1=NO,ARGW2=NO,ARGW3=NO,RETVAL=NO\n");
  3421.       return;
  3422.     }
  3423.  
  3424.   if (GET_CODE (call_insn) != CALL_INSN)
  3425.     abort ();
  3426.   for (link = CALL_INSN_FUNCTION_USAGE (call_insn); link; link = XEXP (link, 1))
  3427.     {
  3428.       rtx use = XEXP (link, 0);
  3429.  
  3430.       if (! (GET_CODE (use) == USE
  3431.          && GET_CODE (XEXP (use, 0)) == REG
  3432.          && FUNCTION_ARG_REGNO_P (REGNO (XEXP (use, 0)))))
  3433.     continue;
  3434.  
  3435.       arg_mode = GET_MODE (XEXP (use, 0));
  3436.       regno = REGNO (XEXP (use, 0));
  3437.       if (regno >= 23 && regno <= 26)
  3438.     {
  3439.       arg_regs[26 - regno] = "GR";
  3440.       if (arg_mode == DImode)
  3441.         arg_regs[25 - regno] = "GR";
  3442.     }
  3443.       else if (regno >= 32 && regno <= 39)
  3444.     {
  3445.       if (arg_mode == SFmode)
  3446.         arg_regs[(regno - 32) / 2] = "FR";
  3447.       else
  3448.         {
  3449. #ifndef HP_FP_ARG_DESCRIPTOR_REVERSED
  3450.           arg_regs[(regno - 34) / 2] = "FR";
  3451.           arg_regs[(regno - 34) / 2 + 1] = "FU";
  3452. #else
  3453.           arg_regs[(regno - 34) / 2] = "FU";
  3454.           arg_regs[(regno - 34) / 2 + 1] = "FR";
  3455. #endif
  3456.         }
  3457.     }
  3458.     }
  3459.   fputs ("\t.CALL ", asm_out_file);
  3460.   for (i = 0; i < 4; i++)
  3461.     {
  3462.       if (arg_regs[i])
  3463.     {
  3464.       if (output_flag++)
  3465.         fputc (',', asm_out_file);
  3466.       fprintf (asm_out_file, "ARGW%d=%s", i, arg_regs[i]);
  3467.     }
  3468.     }
  3469.   fputc ('\n', asm_out_file);
  3470. }
  3471.  
  3472. /* Memory loads/stores to/from the shift need to go through
  3473.    the general registers.  */
  3474.  
  3475. enum reg_class
  3476. secondary_reload_class (class, mode, in)
  3477.      enum reg_class class;
  3478.      enum machine_mode mode;
  3479.      rtx in;
  3480. {
  3481.   int regno = true_regnum (in);
  3482.  
  3483.   /* Trying to load a constant into a FP register during PIC code
  3484.      generation will require %r1 as a scratch register.  */
  3485.   if (flag_pic == 2
  3486.       && GET_MODE_CLASS (mode) == MODE_INT
  3487.       && FP_REG_CLASS_P (class)
  3488.       && (GET_CODE (in) == CONST_INT || GET_CODE (in) == CONST_DOUBLE))
  3489.     return R1_REGS;
  3490.  
  3491.   if (((regno >= FIRST_PSEUDO_REGISTER || regno == -1)
  3492.        && GET_MODE_CLASS (mode) == MODE_INT
  3493.        && FP_REG_CLASS_P (class))
  3494.       || (class == SHIFT_REGS && (regno <= 0 || regno >= 32)))
  3495.     return GENERAL_REGS;
  3496.  
  3497.   if (GET_CODE (in) == HIGH)
  3498.     in = XEXP (in, 0);
  3499.  
  3500.   if (!flag_pic
  3501.       && symbolic_operand (in, VOIDmode)
  3502.       && read_only_operand (in))
  3503.     return NO_REGS;
  3504.  
  3505.   if (class != R1_REGS && symbolic_operand (in, VOIDmode))
  3506.     return R1_REGS;
  3507.  
  3508.   if (GET_CODE (in) == SUBREG)
  3509.     in = SUBREG_REG (in);
  3510.  
  3511.   if (FP_REG_CLASS_P (class)
  3512.       && GET_CODE (in) == MEM
  3513.       && !memory_address_p (DFmode, XEXP (in, 0))
  3514.       && memory_address_p (SImode, XEXP (in, 0)))
  3515.     return GENERAL_REGS;
  3516.  
  3517.   return NO_REGS;
  3518. }
  3519.  
  3520. enum direction
  3521. function_arg_padding (mode, type)
  3522.      enum machine_mode mode;
  3523.      tree type;
  3524. {
  3525.   int size;
  3526.  
  3527.   if (mode == BLKmode)
  3528.     {
  3529.       if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
  3530.     size = int_size_in_bytes (type) * BITS_PER_UNIT;
  3531.       else
  3532.     return upward;        /* Don't know if this is right, but */
  3533.                 /* same as old definition. */
  3534.     }
  3535.   else
  3536.     size = GET_MODE_BITSIZE (mode);
  3537.   if (size < PARM_BOUNDARY)
  3538.     return downward;
  3539.   else if (size % PARM_BOUNDARY)
  3540.     return upward;
  3541.   else
  3542.     return none;
  3543. }
  3544.  
  3545.  
  3546. /* Do what is necessary for `va_start'.  The argument is ignored;
  3547.    We look at the current function to determine if stdargs or varargs
  3548.    is used and fill in an initial va_list.  A pointer to this constructor
  3549.    is returned.  */
  3550.  
  3551. struct rtx_def *
  3552. hppa_builtin_saveregs (arglist)
  3553.      tree arglist;
  3554. {
  3555.   rtx offset;
  3556.   tree fntype = TREE_TYPE (current_function_decl);
  3557.   int argadj = ((!(TYPE_ARG_TYPES (fntype) != 0
  3558.            && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
  3559.                != void_type_node)))
  3560.         ? UNITS_PER_WORD : 0);
  3561.  
  3562.   if (argadj)
  3563.     offset = plus_constant (current_function_arg_offset_rtx, argadj);
  3564.   else
  3565.     offset = current_function_arg_offset_rtx;
  3566.  
  3567.   /* Store general registers on the stack. */
  3568.   move_block_from_reg (23,
  3569.                gen_rtx (MEM, BLKmode,
  3570.                 plus_constant
  3571.                 (current_function_internal_arg_pointer, -16)),
  3572.                4, 4 * UNITS_PER_WORD);
  3573.   return copy_to_reg (expand_binop (Pmode, add_optab,
  3574.                     current_function_internal_arg_pointer,
  3575.                     offset, 0, 0, OPTAB_LIB_WIDEN));
  3576. }
  3577.  
  3578. /* This routine handles all the normal conditional branch sequences we
  3579.    might need to generate.  It handles compare immediate vs compare
  3580.    register, nullification of delay slots, varying length branches,
  3581.    negated branches, and all combinations of the above.  It returns the
  3582.    output appropriate to emit the branch corresponding to all given
  3583.    parameters.  */
  3584.  
  3585. char *
  3586. output_cbranch (operands, nullify, length, negated, insn)
  3587.   rtx *operands;
  3588.   int nullify, length, negated;
  3589.   rtx insn;
  3590. {
  3591.   static char buf[100];
  3592.   int useskip = 0;
  3593.  
  3594.   /* A conditional branch to the following instruction (eg the delay slot) is
  3595.      asking for a disaster.  This can happen when not optimizing.
  3596.  
  3597.      In such cases it is safe to emit nothing.  */
  3598.  
  3599.   if (JUMP_LABEL (insn) == next_nonnote_insn (insn))
  3600.     return "";
  3601.  
  3602.   /* If this is a long branch with its delay slot unfilled, set `nullify'
  3603.      as it can nullify the delay slot and save a nop.  */
  3604.   if (length == 8 && dbr_sequence_length () == 0)
  3605.     nullify = 1;
  3606.  
  3607.   /* If this is a short forward conditional branch which did not get
  3608.      its delay slot filled, the delay slot can still be nullified.  */
  3609.   if (! nullify && length == 4 && dbr_sequence_length () == 0)
  3610.     nullify = forward_branch_p (insn);
  3611.  
  3612.   /* A forward branch over a single nullified insn can be done with a
  3613.      comclr instruction.  This avoids a single cycle penalty due to
  3614.      mis-predicted branch if we fall through (branch not taken).  */
  3615.   if (length == 4
  3616.       && next_real_insn (insn) != 0
  3617.       && get_attr_length (next_real_insn (insn)) == 4
  3618.       && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn))
  3619.       && nullify)
  3620.     useskip = 1;
  3621.  
  3622.   switch (length)
  3623.     {
  3624.       /* All short conditional branches except backwards with an unfilled
  3625.      delay slot.  */
  3626.       case 4:
  3627.     if (useskip)
  3628.       strcpy (buf, "com%I2clr,");
  3629.     else
  3630.       strcpy (buf, "com%I2b,");
  3631.     if (negated)
  3632.       strcat (buf, "%B3");
  3633.     else
  3634.       strcat (buf, "%S3");
  3635.     if (useskip)
  3636.       strcat (buf, " %2,%1,0");
  3637.     else if (nullify)
  3638.       strcat (buf, ",n %2,%1,%0");
  3639.     else
  3640.       strcat (buf, " %2,%1,%0");
  3641.     break;
  3642.  
  3643.      /* All long conditionals.  Note an short backward branch with an
  3644.     unfilled delay slot is treated just like a long backward branch
  3645.     with an unfilled delay slot.  */
  3646.       case 8:
  3647.     /* Handle weird backwards branch with a filled delay slot
  3648.        with is nullified.  */
  3649.     if (dbr_sequence_length () != 0
  3650.         && ! forward_branch_p (insn)
  3651.         && nullify)
  3652.       {
  3653.         strcpy (buf, "com%I2b,");
  3654.         if (negated)
  3655.           strcat (buf, "%S3");
  3656.         else
  3657.           strcat (buf, "%B3");
  3658.         strcat (buf, ",n %2,%1,.+12\n\tbl %0,0");
  3659.       }
  3660.     /* Handle short backwards branch with an unfilled delay slot.
  3661.        Using a comb;nop rather than comiclr;bl saves 1 cycle for both
  3662.        taken and untaken branches.  */
  3663.     else if (dbr_sequence_length () == 0
  3664.          && ! forward_branch_p (insn)
  3665.          && insn_addresses
  3666.          && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
  3667.                     - insn_addresses[INSN_UID (insn)]))
  3668.       {
  3669.         strcpy (buf, "com%I2b,");
  3670.         if (negated)
  3671.           strcat (buf, "%B3 %2,%1,%0%#");
  3672.         else
  3673.           strcat (buf, "%S3 %2,%1,%0%#");
  3674.       }
  3675.     else
  3676.       {
  3677.         strcpy (buf, "com%I2clr,");
  3678.         if (negated)
  3679.           strcat (buf, "%S3");
  3680.         else
  3681.           strcat (buf, "%B3");
  3682.         if (nullify)
  3683.           strcat (buf, " %2,%1,0\n\tbl,n %0,0");
  3684.         else
  3685.           strcat (buf, " %2,%1,0\n\tbl %0,0");
  3686.       }
  3687.     break;
  3688.  
  3689.       default:
  3690.     abort();
  3691.     }
  3692.   return buf;
  3693. }
  3694.  
  3695. /* This routine handles all the branch-on-bit conditional branch sequences we
  3696.    might need to generate.  It handles nullification of delay slots,
  3697.    varying length branches, negated branches and all combinations of the
  3698.    above.  it returns the appropriate output template to emit the branch.  */
  3699.  
  3700. char *
  3701. output_bb (operands, nullify, length, negated, insn, which)
  3702.   rtx *operands;
  3703.   int nullify, length, negated;
  3704.   rtx insn;
  3705.   int which;
  3706. {
  3707.   static char buf[100];
  3708.   int useskip = 0;
  3709.  
  3710.   /* A conditional branch to the following instruction (eg the delay slot) is
  3711.      asking for a disaster.  I do not think this can happen as this pattern
  3712.      is only used when optimizing; jump optimization should eliminate the
  3713.      jump.  But be prepared just in case.  */
  3714.  
  3715.   if (JUMP_LABEL (insn) == next_nonnote_insn (insn))
  3716.     return "";
  3717.  
  3718.   /* If this is a long branch with its delay slot unfilled, set `nullify'
  3719.      as it can nullify the delay slot and save a nop.  */
  3720.   if (length == 8 && dbr_sequence_length () == 0)
  3721.     nullify = 1;
  3722.  
  3723.   /* If this is a short forward conditional branch which did not get
  3724.      its delay slot filled, the delay slot can still be nullified.  */
  3725.   if (! nullify && length == 4 && dbr_sequence_length () == 0)
  3726.     nullify = forward_branch_p (insn);
  3727.  
  3728.   /* A forward branch over a single nullified insn can be done with a
  3729.      extrs instruction.  This avoids a single cycle penalty due to
  3730.      mis-predicted branch if we fall through (branch not taken).  */
  3731.  
  3732.   if (length == 4
  3733.       && next_real_insn (insn) != 0
  3734.       && get_attr_length (next_real_insn (insn)) == 4
  3735.       && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn))
  3736.       && nullify)
  3737.     useskip = 1;
  3738.  
  3739.   switch (length)
  3740.     {
  3741.  
  3742.       /* All short conditional branches except backwards with an unfilled
  3743.      delay slot.  */
  3744.       case 4:
  3745.     if (useskip)
  3746.       strcpy (buf, "extrs,");
  3747.     else
  3748.       strcpy (buf, "bb,");
  3749.     if ((which == 0 && negated)
  3750.          || (which == 1 && ! negated))
  3751.       strcat (buf, ">=");
  3752.     else
  3753.       strcat (buf, "<");
  3754.     if (useskip)
  3755.       strcat (buf, " %0,%1,1,0");
  3756.     else if (nullify && negated)
  3757.       strcat (buf, ",n %0,%1,%3");
  3758.     else if (nullify && ! negated)
  3759.       strcat (buf, ",n %0,%1,%2");
  3760.     else if (! nullify && negated)
  3761.       strcat (buf, "%0,%1,%3");
  3762.     else if (! nullify && ! negated)
  3763.       strcat (buf, " %0,%1,%2");
  3764.     break;
  3765.  
  3766.      /* All long conditionals.  Note an short backward branch with an
  3767.     unfilled delay slot is treated just like a long backward branch
  3768.     with an unfilled delay slot.  */
  3769.       case 8:
  3770.     /* Handle weird backwards branch with a filled delay slot
  3771.        with is nullified.  */
  3772.     if (dbr_sequence_length () != 0
  3773.         && ! forward_branch_p (insn)
  3774.         && nullify)
  3775.       {
  3776.         strcpy (buf, "bb,");
  3777.         if ((which == 0 && negated)
  3778.         || (which == 1 && ! negated))
  3779.           strcat (buf, "<");
  3780.         else
  3781.           strcat (buf, ">=");
  3782.         if (negated)
  3783.           strcat (buf, " %0,%1,.+12\n\tbl %3,0");
  3784.         else
  3785.           strcat (buf, " %0,%1,.+12\n\tbl %2,0");
  3786.       }
  3787.     /* Handle short backwards branch with an unfilled delay slot.
  3788.        Using a bb;nop rather than extrs;bl saves 1 cycle for both
  3789.        taken and untaken branches.  */
  3790.     else if (dbr_sequence_length () == 0
  3791.          && ! forward_branch_p (insn)
  3792.          && insn_addresses
  3793.          && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
  3794.                     - insn_addresses[INSN_UID (insn)]))
  3795.       {
  3796.         strcpy (buf, "bb,");
  3797.         if ((which == 0 && negated)
  3798.         || (which == 1 && ! negated))
  3799.           strcat (buf, ">=");
  3800.         else
  3801.           strcat (buf, "<");
  3802.         if (negated)
  3803.           strcat (buf, " %0,%1,%3%#");
  3804.         else
  3805.           strcat (buf, " %0,%1,%2%#");
  3806.       }
  3807.     else
  3808.       {
  3809.         strcpy (buf, "extrs,");
  3810.         if ((which == 0 && negated)
  3811.         || (which == 1 && ! negated))
  3812.           strcat (buf, "<");
  3813.         else
  3814.           strcat (buf, ">=");
  3815.         if (nullify && negated)
  3816.           strcat (buf, " %0,%1,1,0\n\tbl,n %3,0");
  3817.         else if (nullify && ! negated)
  3818.           strcat (buf, " %0,%1,1,0\n\tbl,n %2,0");
  3819.         else if (negated)
  3820.           strcat (buf, " %0,%1,1,0\n\tbl %3,0");
  3821.         else
  3822.           strcat (buf, " %0,%1,1,0\n\tbl %2,0");
  3823.       }
  3824.     break;
  3825.  
  3826.       default:
  3827.     abort();
  3828.     }
  3829.   return buf;
  3830. }
  3831.  
  3832. /* Return the output template for emitting a dbra type insn.
  3833.  
  3834.    Note it may perform some output operations on its own before
  3835.    returning the final output string.  */
  3836. char *
  3837. output_dbra (operands, insn, which_alternative)
  3838.      rtx *operands;
  3839.      rtx insn;
  3840.      int which_alternative;
  3841. {
  3842.  
  3843.   /* A conditional branch to the following instruction (eg the delay slot) is
  3844.      asking for a disaster.  Be prepared!  */
  3845.  
  3846.   if (JUMP_LABEL (insn) == next_nonnote_insn (insn))
  3847.     {
  3848.       if (which_alternative == 0)
  3849.     return "ldo %1(%0),%0";
  3850.       else if (which_alternative == 1)
  3851.     {
  3852.       output_asm_insn ("fstws %0,-16(0,%%r30)",operands);
  3853.       output_asm_insn ("ldw -16(0,%%r30),%4",operands);
  3854.       output_asm_insn ("ldo %1(%4),%4\n\tstw %4,-16(0,%%r30)", operands);
  3855.       return "fldws -16(0,%%r30),%0";
  3856.     }
  3857.       else
  3858.     {
  3859.       output_asm_insn ("ldw %0,%4", operands);
  3860.       return "ldo %1(%4),%4\n\tstw %4,%0";
  3861.     }
  3862.     }
  3863.  
  3864.   if (which_alternative == 0)
  3865.     {
  3866.       int nullify = INSN_ANNULLED_BRANCH_P (insn);
  3867.       int length = get_attr_length (insn);
  3868.  
  3869.       /* If this is a long branch with its delay slot unfilled, set `nullify'
  3870.      as it can nullify the delay slot and save a nop.  */
  3871.       if (length == 8 && dbr_sequence_length () == 0)
  3872.     nullify = 1;
  3873.  
  3874.       /* If this is a short forward conditional branch which did not get
  3875.      its delay slot filled, the delay slot can still be nullified.  */
  3876.       if (! nullify && length == 4 && dbr_sequence_length () == 0)
  3877.     nullify = forward_branch_p (insn);
  3878.  
  3879.       /* Handle short versions first.  */
  3880.       if (length == 4 && nullify)
  3881.     return "addib,%C2,n %1,%0,%3";
  3882.       else if (length == 4 && ! nullify)
  3883.     return "addib,%C2 %1,%0,%3";
  3884.       else if (length == 8)
  3885.     {
  3886.       /* Handle weird backwards branch with a fulled delay slot
  3887.          which is nullified.  */
  3888.       if (dbr_sequence_length () != 0
  3889.           && ! forward_branch_p (insn)
  3890.           && nullify)
  3891.         return "addib,%N2,n %1,%0,.+12\n\tbl %3,0";
  3892.       /* Handle short backwards branch with an unfilled delay slot.
  3893.          Using a addb;nop rather than addi;bl saves 1 cycle for both
  3894.          taken and untaken branches.  */
  3895.       else if (dbr_sequence_length () == 0
  3896.            && ! forward_branch_p (insn)
  3897.            && insn_addresses
  3898.            && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
  3899.                       - insn_addresses[INSN_UID (insn)]))
  3900.           return "addib,%C2 %1,%0,%3%#";
  3901.  
  3902.       /* Handle normal cases.  */
  3903.       if (nullify)
  3904.         return "addi,%N2 %1,%0,%0\n\tbl,n %3,0";
  3905.       else
  3906.         return "addi,%N2 %1,%0,%0\n\tbl %3,0";
  3907.     }
  3908.       else
  3909.     abort();
  3910.     }
  3911.   /* Deal with gross reload from FP register case.  */
  3912.   else if (which_alternative == 1)
  3913.     {
  3914.       /* Move loop counter from FP register to MEM then into a GR,
  3915.      increment the GR, store the GR into MEM, and finally reload
  3916.      the FP register from MEM from within the branch's delay slot.  */
  3917.       output_asm_insn ("fstws %0,-16(0,%%r30)\n\tldw -16(0,%%r30),%4",operands);
  3918.       output_asm_insn ("ldo %1(%4),%4\n\tstw %4,-16(0,%%r30)", operands);
  3919.       if (get_attr_length (insn) == 24)
  3920.     return "comb,%S2 0,%4,%3\n\tfldws -16(0,%%r30),%0";
  3921.       else
  3922.     return "comclr,%B2 0,%4,0\n\tbl %3,0\n\tfldws -16(0,%%r30),%0";
  3923.     }
  3924.   /* Deal with gross reload from memory case.  */
  3925.   else
  3926.     {
  3927.       /* Reload loop counter from memory, the store back to memory
  3928.      happens in the branch's delay slot.   */
  3929.       output_asm_insn ("ldw %0,%4", operands);
  3930.       if (get_attr_length (insn) == 12)
  3931.     return "addib,%C2 %1,%4,%3\n\tstw %4,%0";
  3932.       else
  3933.     return "addi,%N2 %1,%4,%4\n\tbl %3,0\n\tstw %4,%0";
  3934.     }
  3935. }
  3936.  
  3937. /* Return the output template for emitting a dbra type insn.
  3938.  
  3939.    Note it may perform some output operations on its own before
  3940.    returning the final output string.  */
  3941. char *
  3942. output_movb (operands, insn, which_alternative, reverse_comparison)
  3943.      rtx *operands;
  3944.      rtx insn;
  3945.      int which_alternative;
  3946.      int reverse_comparison;
  3947. {
  3948.  
  3949.   /* A conditional branch to the following instruction (eg the delay slot) is
  3950.      asking for a disaster.  Be prepared!  */
  3951.  
  3952.   if (JUMP_LABEL (insn) == next_nonnote_insn (insn))
  3953.     {
  3954.       if (which_alternative == 0)
  3955.     return "copy %1,%0";
  3956.       else if (which_alternative == 1)
  3957.     {
  3958.       output_asm_insn ("stw %1,-16(0,%%r30)",operands);
  3959.       return "fldws -16(0,%%r30),%0";
  3960.     }
  3961.       else
  3962.     return "stw %1,%0";
  3963.     }
  3964.  
  3965.   /* Support the second variant.  */
  3966.   if (reverse_comparison)
  3967.     PUT_CODE (operands[2], reverse_condition (GET_CODE (operands[2])));
  3968.  
  3969.   if (which_alternative == 0)
  3970.     {
  3971.       int nullify = INSN_ANNULLED_BRANCH_P (insn);
  3972.       int length = get_attr_length (insn);
  3973.  
  3974.       /* If this is a long branch with its delay slot unfilled, set `nullify'
  3975.      as it can nullify the delay slot and save a nop.  */
  3976.       if (length == 8 && dbr_sequence_length () == 0)
  3977.     nullify = 1;
  3978.  
  3979.       /* If this is a short forward conditional branch which did not get
  3980.      its delay slot filled, the delay slot can still be nullified.  */
  3981.       if (! nullify && length == 4 && dbr_sequence_length () == 0)
  3982.     nullify = forward_branch_p (insn);
  3983.  
  3984.       /* Handle short versions first.  */
  3985.       if (length == 4 && nullify)
  3986.     return "movb,%C2,n %1,%0,%3";
  3987.       else if (length == 4 && ! nullify)
  3988.     return "movb,%C2 %1,%0,%3";
  3989.       else if (length == 8)
  3990.     {
  3991.       /* Handle weird backwards branch with a filled delay slot
  3992.          which is nullified.  */
  3993.       if (dbr_sequence_length () != 0
  3994.           && ! forward_branch_p (insn)
  3995.           && nullify)
  3996.         return "movb,%N2,n %1,%0,.+12\n\tbl %3,0";
  3997.  
  3998.       /* Handle short backwards branch with an unfilled delay slot.
  3999.          Using a movb;nop rather than or;bl saves 1 cycle for both
  4000.          taken and untaken branches.  */
  4001.       else if (dbr_sequence_length () == 0
  4002.            && ! forward_branch_p (insn)
  4003.            && insn_addresses
  4004.            && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
  4005.                       - insn_addresses[INSN_UID (insn)]))
  4006.         return "movb,%C2 %1,%0,%3%#";
  4007.       /* Handle normal cases.  */
  4008.       if (nullify)
  4009.         return "or,%N2 %1,%%r0,%0\n\tbl,n %3,0";
  4010.       else
  4011.         return "or,%N2 %1,%%r0,%0\n\tbl %3,0";
  4012.     }
  4013.       else
  4014.     abort();
  4015.     }
  4016.   /* Deal with gross reload from FP register case.  */
  4017.   else if (which_alternative == 1)
  4018.     {
  4019.       /* Move loop counter from FP register to MEM then into a GR,
  4020.      increment the GR, store the GR into MEM, and finally reload
  4021.      the FP register from MEM from within the branch's delay slot.  */
  4022.       output_asm_insn ("stw %1,-16(0,%%r30)",operands);
  4023.       if (get_attr_length (insn) == 12)
  4024.     return "comb,%S2 0,%1,%3\n\tfldws -16(0,%%r30),%0";
  4025.       else
  4026.     return "comclr,%B2 0,%1,0\n\tbl %3,0\n\tfldws -16(0,%%r30),%0";
  4027.     }
  4028.   /* Deal with gross reload from memory case.  */
  4029.   else
  4030.     {
  4031.       /* Reload loop counter from memory, the store back to memory
  4032.      happens in the branch's delay slot.   */
  4033.       if (get_attr_length (insn) == 8)
  4034.     return "comb,%S2 0,%1,%3\n\tstw %1,%0";
  4035.       else
  4036.     return "comclr,%B2 0,%1,0\n\tbl %3,0\n\tstw %1,%0";
  4037.     }
  4038. }
  4039.  
  4040.  
  4041. /* INSN is either a function call or a millicode call.  It may have an
  4042.    unconditional jump in its delay slot.
  4043.  
  4044.    CALL_DEST is the routine we are calling.
  4045.  
  4046.    RETURN_POINTER is the register which will hold the return address.
  4047.    %r2 for most calls, %r31 for millicode calls. 
  4048.  
  4049.    When TARGET_MILLICODE_LONG_CALLS is true, then we have to assume
  4050.    that two instruction sequences must be used to reach the millicode
  4051.    routines (including dyncall!).  */
  4052.  
  4053. char *
  4054. output_call (insn, call_dest, return_pointer)
  4055.   rtx insn;
  4056.   rtx call_dest;
  4057.   rtx return_pointer;
  4058.  
  4059. {
  4060.   int distance;
  4061.   rtx xoperands[4];
  4062.   rtx seq_insn;
  4063.  
  4064.   /* Handle long millicode calls for mod, div, and mul.  */
  4065.   if (TARGET_PORTABLE_RUNTIME
  4066.       || (TARGET_MILLICODE_LONG_CALLS && REGNO (return_pointer) == 31))
  4067.     {
  4068.       xoperands[0] = call_dest;
  4069.       xoperands[1] = return_pointer;
  4070.       output_asm_insn ("ldil L%%%0,%%r29", xoperands);
  4071.       output_asm_insn ("ldo R%%%0(%%r29),%%r29", xoperands);
  4072.       output_asm_insn ("blr 0,%r1\n\tbv,n 0(%%r29)\n\tnop", xoperands);
  4073.       return "";
  4074.     }
  4075.  
  4076.   /* Handle common case -- empty delay slot or no jump in the delay slot,
  4077.      and we're sure that the branch will reach the beginning of the $CODE$
  4078.      subspace.  */
  4079.   if ((dbr_sequence_length () == 0
  4080.        && get_attr_length (insn) == 8)
  4081.       || (dbr_sequence_length () != 0
  4082.       && GET_CODE (NEXT_INSN (insn)) != JUMP_INSN
  4083.       && get_attr_length (insn) == 4))
  4084.     {
  4085.       xoperands[0] = call_dest;
  4086.       xoperands[1] = return_pointer;
  4087.       output_asm_insn ("bl %0,%r1%#", xoperands);
  4088.       return "";
  4089.     }
  4090.  
  4091.   /* This call may not reach the beginning of the $CODE$ subspace.  */
  4092.   if (get_attr_length (insn) > 8)
  4093.     {
  4094.       int delay_insn_deleted = 0;
  4095.       rtx xoperands[2];
  4096.       rtx link;
  4097.  
  4098.       /* We need to emit an inline long-call branch.  Furthermore,
  4099.      because we're changing a named function call into an indirect
  4100.      function call well after the parameters have been set up, we
  4101.      need to make sure any FP args appear in both the integer
  4102.      and FP registers.  Also, we need move any delay slot insn
  4103.      out of the delay slot -- Yuk!  */
  4104.       if (dbr_sequence_length () != 0
  4105.       && GET_CODE (NEXT_INSN (insn)) != JUMP_INSN)
  4106.     {
  4107.       /* A non-jump insn in the delay slot.  By definition we can
  4108.       emit this insn before the call (and in fact before argument
  4109.       relocating.  */
  4110.       final_scan_insn (NEXT_INSN (insn), asm_out_file, optimize, 0, 0);
  4111.  
  4112.       /* Now delete the delay insn.  */
  4113.       PUT_CODE (NEXT_INSN (insn), NOTE);
  4114.       NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED;
  4115.       NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0;
  4116.       delay_insn_deleted = 1;
  4117.     }
  4118.  
  4119.       /* Now copy any FP arguments into integer registers.  */
  4120.       for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
  4121.     {
  4122.       int arg_mode, regno;
  4123.       rtx use = XEXP (link, 0);
  4124.       if (! (GET_CODE (use) == USE
  4125.          && GET_CODE (XEXP (use, 0)) == REG
  4126.          && FUNCTION_ARG_REGNO_P (REGNO (XEXP (use, 0)))))
  4127.         continue;
  4128.  
  4129.       arg_mode = GET_MODE (XEXP (use, 0));
  4130.       regno = REGNO (XEXP (use, 0));
  4131.       /* Is it a floating point register?  */
  4132.       if (regno >= 32 && regno <= 39)
  4133.         {
  4134.           /* Copy from the FP register into an integer register
  4135.          (via memory).  */
  4136.           if (arg_mode == SFmode)
  4137.         {
  4138.           xoperands[0] = XEXP (use, 0);
  4139.           xoperands[1] = gen_rtx (REG, SImode, 26 - (regno - 32) / 2);
  4140.           output_asm_insn ("fstws %0,-16(%%sr0,%%r30)", xoperands);
  4141.           output_asm_insn ("ldw -16(%%sr0,%%r30),%1", xoperands);
  4142.         }
  4143.           else
  4144.         {
  4145.           xoperands[0] = XEXP (use, 0);
  4146.           xoperands[1] = gen_rtx (REG, DImode, 25 - (regno - 34) / 2);
  4147.           output_asm_insn ("fstds %0,-16(%%sr0,%%r30)", xoperands);
  4148.           output_asm_insn ("ldw -12(%%sr0,%%r30),%R1", xoperands);
  4149.           output_asm_insn ("ldw -16(%%sr0,%%r30),%1", xoperands);
  4150.         }
  4151.         
  4152.         }
  4153.     }
  4154.  
  4155.       if (flag_pic)
  4156.     {
  4157.       /* We have to load the address of the function using a procedure
  4158.          label (plabel).  The LP and RP relocs don't work reliably for PIC,
  4159.          so we make a plain 32 bit plabel in the data segment instead.  We
  4160.          have to defer outputting it of course...  Not pretty.  */
  4161.  
  4162.       xoperands[0] = gen_label_rtx ();
  4163.       output_asm_insn ("addil LT%%%0,%%r19\n\tldw RT%%%0(%%r1),%%r22",
  4164.                xoperands);
  4165.       output_asm_insn ("ldw 0(0,%%r22),%%r22", xoperands);
  4166.  
  4167.       if (deferred_plabels == 0)
  4168.         deferred_plabels = (struct defer_plab *)
  4169.           xmalloc (1 * sizeof (struct defer_plab));
  4170.       else
  4171.         deferred_plabels = (struct defer_plab *)
  4172.           xrealloc (deferred_plabels,
  4173.             (n_deferred_plabels + 1) * sizeof (struct defer_plab));
  4174.       deferred_plabels[n_deferred_plabels].internal_label = xoperands[0];
  4175.       deferred_plabels[n_deferred_plabels].symbol = call_dest;
  4176.       n_deferred_plabels++;
  4177.     }
  4178.       else
  4179.     {
  4180.       /* Now emit the inline long-call.  */
  4181.       xoperands[0] = call_dest;
  4182.       output_asm_insn ("ldil LP%%%0,%%r22\n\tldo RP%%%0(%%r22),%%r22",
  4183.                xoperands);
  4184.     }
  4185.  
  4186.       /* If TARGET_MILLICODE_LONG_CALLS, then we must use a long-call sequence
  4187.      to call dyncall!  */
  4188.       if (TARGET_MILLICODE_LONG_CALLS)
  4189.     {
  4190.       output_asm_insn ("ldil L%%$$dyncall,%%r31", xoperands);
  4191.       output_asm_insn ("ldo R%%$$dyncall(%%r31),%%r31", xoperands);
  4192.       output_asm_insn ("blr 0,%%r2\n\tbv,n 0(%%r31)\n\tnop", xoperands);
  4193.     }
  4194.       else
  4195.     output_asm_insn ("bl $$dyncall,%%r31\n\tcopy %%r31,%%r2", xoperands);
  4196.  
  4197.       /* If we had a jump in the call's delay slot, output it now.  */
  4198.       if (dbr_sequence_length () != 0
  4199.       && !delay_insn_deleted)
  4200.     {
  4201.       xoperands[0] = XEXP (PATTERN (NEXT_INSN (insn)), 1);
  4202.       output_asm_insn ("b,n %0", xoperands);
  4203.  
  4204.       /* Now delete the delay insn.  */
  4205.       PUT_CODE (NEXT_INSN (insn), NOTE);
  4206.       NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED;
  4207.       NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0;
  4208.     }
  4209.       return "";
  4210.     }
  4211.  
  4212.   /* This call has an unconditional jump in its delay slot.  */
  4213.  
  4214.   /* Use the containing sequence insn's address.  */
  4215.   seq_insn = NEXT_INSN (PREV_INSN (XVECEXP (final_sequence, 0, 0)));
  4216.  
  4217.   distance = insn_addresses[INSN_UID (JUMP_LABEL (NEXT_INSN (insn)))]
  4218.            - insn_addresses[INSN_UID (seq_insn)] - 8;
  4219.  
  4220.   /* If the branch was too far away, emit a normal call followed
  4221.      by a nop, followed by the unconditional branch.
  4222.  
  4223.      If the branch is close, then adjust %r2 from within the
  4224.      call's delay slot.  */
  4225.  
  4226.   xoperands[0] = call_dest;
  4227.   xoperands[1] = XEXP (PATTERN (NEXT_INSN (insn)), 1);
  4228.   xoperands[2] = return_pointer;
  4229.   if (! VAL_14_BITS_P (distance))
  4230.     output_asm_insn ("bl %0,%r2\n\tnop\n\tbl,n %1,%%r0", xoperands);
  4231.   else
  4232.     {
  4233.       xoperands[3] = gen_label_rtx ();
  4234.       output_asm_insn ("\n\tbl %0,%r2\n\tldo %1-%3(%r2),%r2", xoperands);
  4235.       ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
  4236.                  CODE_LABEL_NUMBER (xoperands[3]));
  4237.     }
  4238.  
  4239.   /* Delete the jump.  */
  4240.   PUT_CODE (NEXT_INSN (insn), NOTE);
  4241.   NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED;
  4242.   NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0;
  4243.   return "";
  4244. }
  4245.  
  4246. extern struct obstack permanent_obstack;
  4247. extern struct obstack *saveable_obstack;
  4248.  
  4249. /* In HPUX 8.0's shared library scheme, special relocations are needed
  4250.    for function labels if they might be passed to a function
  4251.    in a shared library (because shared libraries don't live in code
  4252.    space), and special magic is needed to construct their address.
  4253.  
  4254.    For reasons too disgusting to describe storage for the new name
  4255.    is allocated either on the saveable_obstack (released at function
  4256.    exit) or on the permanent_obstack for things that can never change
  4257.    (libcall names for example). */
  4258.  
  4259. void
  4260. hppa_encode_label (sym, permanent)
  4261.      rtx sym;
  4262.      int permanent;
  4263. {
  4264.   char *str = XSTR (sym, 0);
  4265.   int len = strlen (str);
  4266.   char *newstr;
  4267.  
  4268.   newstr = obstack_alloc ((permanent ? &permanent_obstack : saveable_obstack),
  4269.               len + 2);
  4270.  
  4271.   if (str[0] == '*')
  4272.     *newstr++ = *str++;
  4273.   strcpy (newstr + 1, str);
  4274.   *newstr = '@';
  4275.   XSTR (sym,0) = newstr;
  4276. }
  4277.  
  4278. int
  4279. function_label_operand (op, mode)
  4280.      rtx op;
  4281.      enum machine_mode mode;
  4282. {
  4283.   return GET_CODE (op) == SYMBOL_REF && FUNCTION_NAME_P (XSTR (op, 0));
  4284. }
  4285.  
  4286. /* Returns 1 if OP is a function label involved in a simple addition
  4287.    with a constant.  Used to keep certain patterns from matching
  4288.    during instruction combination.  */
  4289. int
  4290. is_function_label_plus_const (op)
  4291.      rtx op;
  4292. {
  4293.   /* Strip off any CONST.  */
  4294.   if (GET_CODE (op) == CONST)
  4295.     op = XEXP (op, 0);
  4296.  
  4297.   return (GET_CODE (op) == PLUS
  4298.       && function_label_operand (XEXP (op, 0), Pmode)
  4299.       && GET_CODE (XEXP (op, 1)) == CONST_INT);
  4300. }
  4301.  
  4302. /* Returns 1 if the 6 operands specified in OPERANDS are suitable for
  4303.    use in fmpyadd instructions.  */
  4304. int
  4305. fmpyaddoperands (operands)
  4306.      rtx *operands;
  4307. {
  4308.   enum machine_mode mode = GET_MODE (operands[0]);
  4309.  
  4310.   /* All modes must be the same.  */
  4311.   if (! (mode == GET_MODE (operands[1])
  4312.      && mode == GET_MODE (operands[2])
  4313.      && mode == GET_MODE (operands[3])
  4314.      && mode == GET_MODE (operands[4])
  4315.      && mode == GET_MODE (operands[5])))
  4316.     return 0;
  4317.  
  4318.   /* Both DFmode and SFmode should work.  But using SFmode makes the
  4319.      assembler complain.  Just turn it off for now.  */
  4320.   if (mode != DFmode)
  4321.     return 0;
  4322.  
  4323.   /* Only 2 real operands to the addition.  One of the input operands must
  4324.      be the same as the output operand.  */
  4325.   if (! rtx_equal_p (operands[3], operands[4])
  4326.       && ! rtx_equal_p (operands[3], operands[5]))
  4327.     return 0;
  4328.  
  4329.   /* Inout operand of add can not conflict with any operands from multiply.  */
  4330.   if (rtx_equal_p (operands[3], operands[0])
  4331.      || rtx_equal_p (operands[3], operands[1])
  4332.      || rtx_equal_p (operands[3], operands[2]))
  4333.     return 0;
  4334.  
  4335.   /* multiply can not feed into addition operands.  */
  4336.   if (rtx_equal_p (operands[4], operands[0])
  4337.       || rtx_equal_p (operands[5], operands[0]))
  4338.     return 0;
  4339.  
  4340.   /* Passed.  Operands are suitable for fmpyadd.  */
  4341.   return 1;
  4342. }
  4343.  
  4344. /* Returns 1 if the 6 operands specified in OPERANDS are suitable for
  4345.    use in fmpysub instructions.  */
  4346. int
  4347. fmpysuboperands (operands)
  4348.      rtx *operands;
  4349. {
  4350.   enum machine_mode mode = GET_MODE (operands[0]);
  4351.  
  4352.   /* All modes must be the same.  */
  4353.   if (! (mode == GET_MODE (operands[1])
  4354.      && mode == GET_MODE (operands[2])
  4355.      && mode == GET_MODE (operands[3])
  4356.      && mode == GET_MODE (operands[4])
  4357.      && mode == GET_MODE (operands[5])))
  4358.     return 0;
  4359.  
  4360.   /* Both DFmode and SFmode should work.  But using SFmode makes the
  4361.      assembler complain.  Just turn it off for now.  */
  4362.   if (mode != DFmode)
  4363.     return 0;
  4364.  
  4365.   /* Only 2 real operands to the subtraction.  Subtraction is not a commutative
  4366.      operation, so operands[4] must be the same as operand[3].  */
  4367.   if (! rtx_equal_p (operands[3], operands[4]))
  4368.     return 0;
  4369.  
  4370.   /* multiply can not feed into subtraction.  */
  4371.   if (rtx_equal_p (operands[5], operands[0]))
  4372.     return 0;
  4373.  
  4374.   /* Inout operand of sub can not conflict with any operands from multiply.  */
  4375.   if (rtx_equal_p (operands[3], operands[0])
  4376.      || rtx_equal_p (operands[3], operands[1])
  4377.      || rtx_equal_p (operands[3], operands[2]))
  4378.     return 0;
  4379.  
  4380.   /* Passed.  Operands are suitable for fmpysub.  */
  4381.   return 1;
  4382. }
  4383.  
  4384. int
  4385. plus_xor_ior_operator (op, mode)
  4386.      rtx op;
  4387.      enum machine_mode mode;
  4388. {
  4389.   return (GET_CODE (op) == PLUS || GET_CODE (op) == XOR
  4390.       || GET_CODE (op) == IOR);
  4391. }
  4392.  
  4393. /* Return 1 if the given constant is 2, 4, or 8.  These are the valid
  4394.    constants for shadd instructions.  */
  4395. int
  4396. shadd_constant_p (val)
  4397.      int val;
  4398. {
  4399.   if (val == 2 || val == 4 || val == 8)
  4400.     return 1;
  4401.   else
  4402.     return 0;
  4403. }
  4404.  
  4405. /* Return 1 if OP is a CONST_INT with the value 2, 4, or 8.  These are
  4406.    the valid constant for shadd instructions.  */
  4407. int
  4408. shadd_operand (op, mode)
  4409.      rtx op;
  4410.      enum machine_mode mode;
  4411. {
  4412.   return (GET_CODE (op) == CONST_INT && shadd_constant_p (INTVAL (op)));
  4413. }
  4414.  
  4415. /* Return 1 if this operand is anything other than a hard register.  */
  4416.  
  4417. int
  4418. non_hard_reg_operand (op, mode)
  4419.      rtx op;
  4420.      enum machine_mode mode;
  4421. {
  4422.   return ! (GET_CODE (op) == REG && REGNO (op) < FIRST_PSEUDO_REGISTER);
  4423. }
  4424.  
  4425. /* Return 1 if INSN branches forward.  Should be using insn_addresses
  4426.    to avoid walking through all the insns... */
  4427. int
  4428. forward_branch_p (insn)
  4429.      rtx insn;
  4430. {
  4431.   rtx label = JUMP_LABEL (insn);
  4432.  
  4433.   while (insn)
  4434.     {
  4435.       if (insn == label)
  4436.     break;
  4437.       else
  4438.     insn = NEXT_INSN (insn);
  4439.     }
  4440.  
  4441.   return (insn == label);
  4442. }
  4443.  
  4444. /* Return 1 if OP is an equality comparison, else return 0.  */
  4445. int
  4446. eq_neq_comparison_operator (op, mode)
  4447.      rtx op;
  4448.      enum machine_mode mode;
  4449. {
  4450.   return (GET_CODE (op) == EQ || GET_CODE (op) == NE);
  4451. }
  4452.  
  4453. /* Return 1 if OP is an operator suitable for use in a movb instruction.  */
  4454. int
  4455. movb_comparison_operator (op, mode)
  4456.      rtx op;
  4457.      enum machine_mode mode;
  4458. {
  4459.   return (GET_CODE (op) == EQ || GET_CODE (op) == NE
  4460.       || GET_CODE (op) == LT || GET_CODE (op) == GE);
  4461. }
  4462.  
  4463. /* Return 1 if INSN is in the delay slot of a call instruction.  */
  4464. int
  4465. jump_in_call_delay (insn)
  4466.      rtx insn;
  4467. {
  4468.  
  4469.   if (GET_CODE (insn) != JUMP_INSN)
  4470.     return 0;
  4471.  
  4472.   if (PREV_INSN (insn)
  4473.       && PREV_INSN (PREV_INSN (insn))
  4474.       && GET_CODE (next_active_insn (PREV_INSN (PREV_INSN (insn)))) == INSN)
  4475.     {
  4476.       rtx test_insn = next_active_insn (PREV_INSN (PREV_INSN (insn)));
  4477.  
  4478.       return (GET_CODE (PATTERN (test_insn)) == SEQUENCE
  4479.           && XVECEXP (PATTERN (test_insn), 0, 1) == insn);
  4480.  
  4481.     }
  4482.   else
  4483.     return 0;
  4484. }
  4485.  
  4486.  
  4487. /* We use this hook to perform a PA specific optimization which is difficult
  4488.    to do in earlier passes.
  4489.  
  4490.    We want the delay slots of branches within jump tables to be filled.
  4491.    None of the compiler passes at the moment even has the notion that a
  4492.    PA jump table doesn't contain addresses, but instead contains actual
  4493.    instructions!
  4494.  
  4495.    Because we actually jump into the table, the addresses of each entry
  4496.    must stay constant in relation to the beginning of the table (which
  4497.    itself must stay constant relative to the instruction to jump into
  4498.    it).  I don't believe we can guarantee earlier passes of the compiler
  4499.    will adhere to those rules.
  4500.  
  4501.    So, late in the compilation process we find all the jump tables, and
  4502.    expand them into real code -- eg each entry in the jump table vector
  4503.    will get an appropriate label followed by a jump to the final target.
  4504.  
  4505.    Reorg and the final jump pass can then optimize these branches and
  4506.    fill their delay slots.  We end up with smaller, more efficient code.
  4507.  
  4508.    The jump instructions within the table are special; we must be able 
  4509.    to identify them during assembly output (if the jumps don't get filled
  4510.    we need to emit a nop rather than nullifying the delay slot)).  We
  4511.    identify jumps in switch tables by marking the SET with DImode.  */
  4512.  
  4513. pa_reorg (insns)
  4514.      rtx insns;
  4515. {
  4516.   rtx insn;
  4517.  
  4518.   /* This is fairly cheap, so always run it if optimizing.  */
  4519.   if (optimize > 0)
  4520.     {
  4521.       /* Find and explode all ADDR_VEC insns.  */
  4522.       insns = get_insns ();
  4523.       for (insn = insns; insn; insn = NEXT_INSN (insn))
  4524.     {
  4525.       rtx pattern, tmp, location;
  4526.       unsigned int length, i;
  4527.  
  4528.       /* Find an ADDR_VEC insn to explode.  */
  4529.       if (GET_CODE (insn) != JUMP_INSN
  4530.           || GET_CODE (PATTERN (insn)) != ADDR_VEC)
  4531.         continue;
  4532.  
  4533.       pattern = PATTERN (insn);
  4534.       location = PREV_INSN (insn);
  4535.           length = XVECLEN (pattern, 0);
  4536.       for (i = 0; i < length; i++)
  4537.         {
  4538.           /* Emit the jump itself.  */
  4539.           tmp = gen_switch_jump (XEXP (XVECEXP (pattern, 0, i), 0));
  4540.           tmp = emit_jump_insn_after (tmp, location);
  4541.           JUMP_LABEL (tmp) = XEXP (XVECEXP (pattern, 0, i), 0);
  4542.           LABEL_NUSES (JUMP_LABEL (tmp))++;
  4543.  
  4544.           /* Emit a BARRIER after the jump.  */
  4545.           location = NEXT_INSN (location);
  4546.           emit_barrier_after (location);
  4547.  
  4548.           /* Put a CODE_LABEL before each so jump.c does not optimize
  4549.          the jumps away.  */
  4550.           location = NEXT_INSN (location);
  4551.           tmp = gen_label_rtx ();
  4552.           LABEL_NUSES (tmp) = 1;
  4553.           emit_label_after (tmp, location);
  4554.           location = NEXT_INSN (location);
  4555.         }
  4556.       /* Delete the ADDR_VEC.  */
  4557.       delete_insn (insn);
  4558.     }
  4559.     }
  4560. }
  4561.